分享

3DES的CBC加密模式

 wythe 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 <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$

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多