淺析CBC加密算法

如果SA加密組件中數(shù)據(jù)加密算法的標(biāo)識符等于0x01,那么將使用CBC模式的DES算法來加密與該SA相關(guān)聯(lián)的業(yè)務(wù)數(shù)據(jù)。使用DES-CBC(Data Encryption Standard-Cipher Block Chaining,密碼分組鏈接模式下的數(shù)據(jù)加密標(biāo)準(zhǔn))技術(shù),可以對MACPDU的載荷域進(jìn)行加密,但無法對通用MAC頭(Generic MAC Header,GMH)和循環(huán)冗余校驗 (CRC)數(shù)據(jù)進(jìn)行加密。DES-CBC的加密過程如圖所示

淺析CBC加密算法

實現(xiàn)密碼分組鏈接(CBC)模式需要一個初始化向量(Initialization Vector IV),該微量是通過將安全關(guān)聯(lián)(Security Association,SA)中的初始化向量(1V)參數(shù)與物理層同步域內(nèi)容進(jìn)行異或(Exclusive OR, XOR)運算得到的。CBCIV的計算方法是:在下行鏈路上,CBC的初始化是通過將TEK密鑰信息中的IV參數(shù)與最新 DL-MAP中的物理層同步域的內(nèi)容進(jìn)行異或運算來實現(xiàn)的;在上行鏈路上,CBC的初始化是通過將TEK密鑰信息中的IV參數(shù)與DL-MAP中的物理層同步域的內(nèi)容進(jìn)行異或運算來實現(xiàn)的,這個DL— MAP在當(dāng)前UL-MAP被創(chuàng)建或接收到時必須是有效的。

DES加密過程使用連接安全關(guān)聯(lián)中的初始化向量(1V)和傳輸加密密鑰 (Traffic Encryption Key,TEK),來對 PDU載荷進(jìn)行加密。然后,密文載荷代替原始明文載荷。GMH中的EC(En- cryption Control,加密控制)位為1時,表示對載荷進(jìn)行加密操作;加密密鑰序列(Encryption Key Sequence,EKS)字段只有在 EC字段設(shè)置成1時才有效,用于表示傳輸加密密鑰和初始向量的序號將被用于載荷加密。對于新的密文載荷,如果包含了CRC,則需要對其進(jìn)行更新。

總體而言,DES-CBC加密方案具有較低的安全性,這一方面是由于DES算法本身的脆弱性造成的,另一方面是用于這種加密方法的數(shù)據(jù)封裝沒有完整性和抗重放保護(hù)機制。

CBC模式下的數(shù)據(jù)加密和解密詳細(xì)描述

Cipher-block chaining(CBC)是一種加密方式,它將純文本分塊和之前加密的密文塊進(jìn)行XOR操作。這里每個密文塊都取決于純文本的這種處理。注意要確保消息獨立,并在第一個塊中使用初始向量。

Symbian Cryptography library的CModeCBCEncryptor可以用來加密數(shù)據(jù),它使用CBlockTransformation子類在它隨后擁有的CAESEncryptor中進(jìn)行初始化。下列代碼演示了對CBC模式下的數(shù)據(jù)塊加密和解密的操作。

解決方案

CBC模式下對數(shù)據(jù)的加密

復(fù)制到剪貼板 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模式下對數(shù)據(jù)的解密:

復(fù)制到剪貼板 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模式的初始向量,長度是加密塊長,可以任意設(shè)定 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");

}//加密文件結(jié)束

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);

}//解密文件結(jié)束

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; }