2023-06-26
3DES的CBC加密模式在原始DES的CBC模式基础上进行了扩展。它使用三个56位的密钥进行加密,并使用加密向量以及块加密模式进行加密和解密过程。
在使用3DES的CBC模式时,加密过程的大致流程如下:
(相关资料图)
1. 将明文按照块长度分成若干个64位的块,如果最后一个块大小不足块长度,则使用填充方式进行补齐。
2. 将三个密钥分为3个8字节大小的块k1、k2、k3。
3. 选定一个初始化向量IV。
4. 对明文第1块进行加密:使用密钥k1对明文第1块进行DES加密,得到C1;使用密钥k2对C1进行DES解密,得到C1";使用密钥k3对C1"进行DES加密,得到C1""。
5. 对后续的块进行加密:使用密钥k1对明文第i块与前面的密文Ci-1异或后的结果进行DES加密,得到Ci;使用密钥k2对Ci进行DES解密,得到Ci";再使用密钥k3对Ci"进行DES加密,得到Ci""。
6. 对加密结果进行CBC加密:将初始化向量IV与第1块密文C1""进行异或操作,得到Ci""的CBC初始化向量IVi,并对Ci""进行加密得到第i块密文柿Pi=Ci"" ⊕ IVi+1。
7. 将第i块密文P1、P2、...、Pn连接起来,得到密文串C。
在解密过程中,需要先进行CBC解密,然后进行3次DES解密。
综上所述,3DES的CBC加密模式相比普通的DES-ECB模式更加安全可靠,因此它在通信和数据传输中被广泛使用。
下面是调用OpenSSL的实现方式:
#include#include #include #include #include #defineBLOCK_SIZE8#defineCBC2#defineCFB1#defineECB0staticintDes_ede3_cbc_encrypt(constunsignedchar*key,intkeyLen,constunsignedchar*in,intinLen,unsignedchar*out,unsignedchar*iv,inten){DES_key_scheduleks1,ks2,ks3;//DES_cblockkey1,key2,key3;unsignedcharke1[8],ke2[8],ke3[8],ivec[8];printf("keyLen=%dinLen=%d\n",keyLen,inLen);if(key==NULL||keyLen==0)return-1;//memcpy(key1,key+BLOCK_SIZE*0,BLOCK_SIZE);//memcpy(key2,key+BLOCK_SIZE*1,BLOCK_SIZE);//memcpy(key3,key+BLOCK_SIZE*2,BLOCK_SIZE);memcpy(ivec,iv,8);memcpy(ke1,key+0,8);memcpy(ke2,key+8,8);memcpy(ke3,key+16,8);//DES_set_key((const_DES_cblock*)key1,&ks1);//DES_set_key((const_DES_cblock*)key2,&ks2);//DES_set_key((const_DES_cblock*)key3,&ks3);DES_set_key_unchecked((const_DES_cblock*)ke1,&ks1);DES_set_key_unchecked((const_DES_cblock*)ke2,&ks2);DES_set_key_unchecked((const_DES_cblock*)ke3,&ks3);//printHex("key1",key1,8);//printHex("key2",key2,8);//printHex("key3",key3,8);if(DES_DECRYPT==en){DES_ede3_cbc_encrypt(in,out,inLen,&ks1,&ks2,&ks3,(DES_cblock*)ivec,DES_DECRYPT);}else{DES_ede3_cbc_encrypt(in,out,inLen,&ks1,&ks2,&ks3,(DES_cblock*)ivec,DES_ENCRYPT);}return0;}intmain(intargc,char**argv){intplain_len=0;inti=0;intcipher_len=0;//intout_len=0;unsignedchar*clear_text=NULL;unsignedchar*cipher_text=NULL;unsignedcharenkey[]={0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,//0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,//0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c,//0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6};constunsignedcharplaintext[]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,//0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19};unsignedchariv[]={0x3b,0x4e,0x21,0x1e,0x58,0x1d,0xa3,0x73,//0x5d,0x8f,0x01,0xba,0xa3,0x7b,0x8f,0xce};//unsignedchariv[]={0};plain_len=sizeof(plaintext);if(plain_len%BLOCK_SIZE!=0)cipher_len=plain_len+BLOCK_SIZE-plain_len%BLOCK_SIZE;elsecipher_len=plain_len;cipher_text=malloc(cipher_len);if(NULL==cipher_text){printf("cipher_textallocmemoryfailed\n");gotoexits;}clear_text=malloc(cipher_len);if(NULL==clear_text){printf("clear_textallocmemoryfailed\n");gotoexits;}/*for(i=0;i 执行结果:
wythe@xxxx:~/linux-sys/tls$./des_cbckeyLen=24inLen=24Ciphertext:62D0F142BD7FCB9A29866EEC7371568CC581EFF68F23F51CkeyLen=24inLen=24Cleartext:0102030405060708090A0B0C0E0F10111213141516171819wythe@xxxx:~/linux-sys/tls$