如果SA加密组件中数据加密算法的标识符等于0x01,那么将使用CBC模式的DES算法来加密与该SA相关联的业务数据。使用DES-CBC(Data Encryption Standard-Cipher Block Chaining,密码分组链接模式下的数据加密标准)技术,可以对MACPDU的载荷域进行加密,但无法对通用MAC头(Generic MAC Header,GMH)和循环冗余校验 (CRC)数据进行加密。DES-CBC的加密过程如图所示

浅析CBC加密算法

实现密码分组链接(CBC)模式需要一个初始化向量(Initialization Vector IV),该微量是通过将安全关联(Security Association,SA)中的初始化向量(1V)参数与物理层同步域内容进行异或(Exclusive OR, XOR)运算得到的。CBCIV的计算方法是:在下行链路上,CBC的初始化是通过将TEK密钥信息中的IV参数与最新 DL-MAP中的物理层同步域的内容进行异或运算来实现的;在上行链路上,CBC的初始化是通过将TEK密钥信息中的IV参数与DL-MAP中的物理层同步域的内容进行异或运算来实现的,这个DL— MAP在当前UL-MAP被创建或接收到时必须是有效的。

DES加密过程使用连接安全关联中的初始化向量(1V)和传输加密密钥 (Traffic Encryption Key,TEK),来对 PDU载荷进行加密。然后,密文载荷代替原始明文载荷。GMH中的EC(En- cryption Control,加密控制)位为1时,表示对载荷进行加密操作;加密密钥序列(Encryption Key Sequence,EKS)字段只有在 EC字段设置成1时才有效,用于表示传输加密密钥和初始向量的序号将被用于载荷加密。对于新的密文载荷,如果包含了CRC,则需要对其进行更新。

总体而言,DES-CBC加密方案具有较低的安全性,这一方面是由于DES算法本身的脆弱性造成的,另一方面是用于这种加密方法的数据封装没有完整性和抗重放保护机制。

CBC模式下的数据加密和解密详细描述

Cipher-block chaining(CBC)是一种加密方式,它将纯文本分块和之前加密的密文块进行XOR操作。这里每个密文块都取决于纯文本的这种处理。注意要确保消息独立,并在第一个块中使用初始向量。

Symbian Cryptography library的CModeCBCEncryptor可以用来加密数据,它使用CBlockTransformation子类在它随后拥有的CAESEncryptor中进行初始化。下列代码演示了对CBC模式下的数据块加密和解密的操作。

解决方案

CBC模式下对数据的加密

复制到剪贴板 C/C++代码

1. void CCBCExAppUi::CBCEncryption(TPtr8& aDataPtr) { CAESEncryptor* ae sEncryptor = CAESEncryptor::NewL(iCipherkey); CModeCBCEncryptor* cbcEncryptor = CModeCBCEncryptor::NewLC(aesEncryptor,

iIV);<br> for(TInt i = 0; i<3; i++) { TPtr8 tempDataptr = aDataPtr.MidTPtr(16*i,16); cbcEncryptor->Transform(tempDataptr); cbcEncryptor->SetIV(tempDataptr); }<br>

CleanupStack::PopAndDestroy(); }

CBC模式下对数据的解密:

复制到剪贴板 C/C++代码
1. void CCBCExAppUi::CBCDecryption(TPtr8& aDataPtr) { CAESDecryptor* aes decryptor = CAESDecryptor::NewL(iCipherkey); CModeCBCDecryptor* cbcDecryptor = CModeCBCDecryptor::NewLC(aesdecryptor,
iIV);<br> TBuf8<16>tempBuf; for(TInt i = 0; i<3; i++) { TPtr8 tempDataptr = aDataPtr.MidTPtr(16*i,16); tempBuf.Copy(tempDataptr); cbcDecryptor->Transform(tempDataptr); cbcDecryptor->SetIV(tempBuf); }<br> CleanupStack::PopAndDestroy(); }

2. ////////////////////////////////////////////

//This modules is the main()

//author:Jing Jiandu

//2002-11-25

//notes: the block length is 16 bytes

////////////////////////////////////////////

#include "stdafx.h"

#include "windows.h"

#include "CAes.h"

#include <stdio.h>

#pragma comment(lib,"CAes.lib")

3. BOOL isEndOfFile(FILE *fp);

4. void main(int argc, char* argv[])

{CCAes CaesObj(128);

int blockLen=CaesObj.BlockByteLen;

int keyLen=CaesObj.KeyByteLen;

BYTE iv[4][4]={0,1,0,0, //CBC模式的初始向量,长度是加密块长,可以任意设定 0,0,2,0,

0,0,0,6,

0,0,0,0};

LPBYTE state=new BYTE[blockLen];

LPBYTE midState=new

BYTE[blockLen];

LPBYTE temp;

LPBYTE p_iv=*iv;

BYTE w1[16]={"AES-CRYPTION"};

char userKey[100]; int count; int i; FILE *fpr,*fpw;

char filename1[20],filename2[20],c;

printf("You want to encrypt or decrypt a file?[e/d]");

scanf("%c",&c);

5. if (c=='e'||c=='E') //加密文件过程

{ printf(">-----------------------------------------------\nPlease input filename you want to encrypt:\n");

scanf("%s",filename1);

if ((fpr=fopen(filename1,"rb"))==NULL)

{ printf("Sorry! Cannot open this file\n");
return; } if ((fpw=fopen(strcat(filename1,".aes"),"wb+"))==NULL) { printf("Cannot open this file\n");

return; } printf("Please input your key no more than %d chars!\n",keyLen); scanf("%s",userKey);

CaesObj.keyexpansion(userKey);

printf("Encryption is going on, please waiting........\n");

6. fwrite(w1,1,16,fpw);

i=-1;

while(1)

{ ++i%=3;

if((count=fread(state,1,blockLen,fpr))<blockLen) { memset(state+count,'\0',blockLen-count); }

7. if(i==0) CaesObj.blockxor(state,p_iv,blockLen);

else CaesObj.blockxor(state,midState,blockLen);

CaesObj.rijndael(state); memcpy(midState,state,blockLen);

fwrite(state,1,blockLen,fpw);

8. if(feof(fpr)) { fseek(fpw,15,0);

fputc((BYTE)count,fpw); break; } }

9. fclose(fpr);

fclose(fpw);

printf("Encryption is over,press anykey to return.\n");

}//加密文件结束

else if(c=='d'||c=='D') //解密文件过程

{ printf("Please input filename you want to decrypt:\n");

scanf("%s",filename1);

printf("Please input filename after decryption:\n");

scanf("%s",filename2);
if ((fpr=fopen(filename1,"rb"))==NULL)

{ printf("Cannot open this file\n"); return; } if ((fpw=fopen(filename2,"wb+"))==NULL) { printf("Cannot open this file\n");

return; } printf("Please input your key no more than %d chars!\n",keyLen);

scanf("%s",userKey); CaesObj.keyexpansion(userKey);

fread(w1,1,15,fpr); BYTE co; fread(&co,sizeof(BYTE),1,fpr);

temp=new BYTE[blockLen]; 10. i=-1;

11. while(1) { ++i%=3; fread(state,1,blockLen,fpr);

memcpy(midState,temp,blockLen);

memcpy(temp,state,blockLen);

CaesObj.invrijndael(state);

if(i==0) CaesObj.blockxor(state,p_iv,blockLen);

else CaesObj.blockxor(state,midState,blockLen);

12. if(isEndOfFile(fpr)) { fwrite(state,1,co,fpw);

break; 13. } else { fwrite(state,1,blockLen,fpw);

} } delete []temp; fclose(fpr);
fclose(fpw);

}//解密文件结束

14.delete []state; delete []midState;

} //the end of main()

15.BOOL isEndOfFile(FILE *fp) { BOOL res; 16.fgetc(fp);

res=feof(fp);

fseek(fp,-1,1); 17.return res; }