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 <stdio.h> #include <string.h> #include <stdlib.h> #include <openssl/des.h> #include <openssl/evp.h> #define BLOCK_SIZE 8 #define CBC 2 #define CFB 1 #define ECB 0 static int Des_ede3_cbc_encrypt(const unsigned char *key, int keyLen, const unsigned char *in, int inLen, unsigned char *out, unsigned char *iv, int en) { DES_key_schedule ks1,ks2,ks3; //DES_cblock key1,key2,key3; unsigned char ke1[8], ke2[8], ke3[8], ivec[8]; printf("keyLen =%d inLen=%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); } return 0; } int main(int argc,char ** argv ) { int plain_len = 0; int i = 0; int cipher_len = 0; //int out_len = 0; unsigned char * clear_text = NULL; unsigned char * cipher_text = NULL; unsigned char enkey[] = { 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 }; const unsigned char plaintext[] = { 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 }; unsigned char iv[] = {0x3b, 0x4e, 0x21, 0x1e, 0x58, 0x1d, 0xa3, 0x73, //0x5d, 0x8f, 0x01, 0xba, 0xa3, 0x7b, 0x8f, 0xce }; //unsigned char iv[] = {0}; plain_len = sizeof (plaintext); if(plain_len%BLOCK_SIZE != 0) cipher_len = plain_len + BLOCK_SIZE - plain_len%BLOCK_SIZE; else cipher_len = plain_len; cipher_text = malloc(cipher_len); if(NULL == cipher_text) { printf("cipher_text alloc memory failed\n"); goto exits; } clear_text = malloc(cipher_len); if(NULL == clear_text) { printf("clear_text alloc memory failed\n"); goto exits; } /*for(i = 0; i < cipher_len ; i+=8 ) { DES_ede3_cbc_encrypt(plaintext + i, cipher_text + i, 8, &ks1, &ks2, &ks3, (DES_cblock *)iv, DES_ENCRYPT); printf("i =%d encrypt \n",i); }*/ /*DES_ede3_cbc_encrypt(plaintext , cipher_text, cipher_len, &ks1, &ks2, &ks3, (DES_cblock *)iv, DES_ENCRYPT);*/ //des3_encrypt(enkey,iv,plaintext,cipher_len,cipher_text,&out_len); /*DesEncryptData(enkey, sizeof(enkey), plaintext, cipher_len, CBC, iv, cipher_text);*/ Des_ede3_cbc_encrypt(enkey, sizeof(enkey), plaintext, sizeof(plaintext), cipher_text, iv, DES_ENCRYPT); printf("Cipher text: "); for (i = 0; i < cipher_len ; i++) { printf("%02X ", cipher_text[i]); } printf("\n"); /*for(i = 0; i < cipher_len ; i+=8 ) { DES_ede3_cbc_encrypt(cipher_text + i, clear_text + i, 8, &ks1, &ks2, &ks3, (DES_cblock *)iv, DES_DECRYPT); printf("i =%d decrypt \n",i); }*/ /*DES_ede3_cbc_encrypt(cipher_text , clear_text , cipher_len, &ks1, &ks2, &ks3, (DES_cblock *)iv, DES_DECRYPT);*/ //DesEncryptData(); /*DesDecryptData(enkey, sizeof(enkey), cipher_text, cipher_len, CBC, iv, clear_text);*/ Des_ede3_cbc_encrypt(enkey, sizeof(enkey), cipher_text, cipher_len, clear_text, iv, DES_DECRYPT); printf("Clear text: "); for (i = 0; i < cipher_len ; i++) { printf("%02X ", clear_text[i]); } printf("\n"); exits: if(cipher_text != NULL ) { free(cipher_text); } if(clear_text != NULL ) { free(clear_text); } return 0; } 执行结果: wythe@xxxx:~/linux-sys/tls$ ./des_cbc keyLen =24 inLen=24 Cipher text: 62 D0 F1 42 BD 7F CB 9A 29 86 6E EC 73 71 56 8C C5 81 EF F6 8F 23 F5 1C keyLen =24 inLen=24 Clear text: 01 02 03 04 05 06 07 08 09 0A 0B 0C 0E 0F 10 11 12 13 14 15 16 17 18 19 wythe@xxxx:~/linux-sys/tls$ |
|