# 加解密：基于 openssl 实现 des ede3 cbc pkcs#5 算法

## 加解密：基于 openssl 实现 des ede3 cbc pkcs#5 算法

Code：

#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/x509.h>

void encrypt_des_ede_cbc_pkcs(
unsigned char *in,		// 待加密数据
unsigned int   inLen,	// 待加密数据字节数
unsigned char *key,		// 密  钥，长度总是24字节
unsigned char *iv)		// 偏移量，长度总是08字节
{
printf("encrypt......\n\n");

unsigned char *outBuf;
unsigned int outBufLen, outLen1, outLen2;

/* 依据PKCS填充规则 */
outBufLen = (inLen/8 + 1) * 8;
outBuf = (unsigned char *)malloc(outBufLen);

EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_EncryptInit_ex(&ctx, EVP_des_ede3_cbc(), NULL, key, iv);
EVP_EncryptUpdate(&ctx, outBuf, &outLen1, in, inLen);
EVP_EncryptFinal_ex(&ctx, outBuf+outLen1, &outLen2);

unsigned int i;
for (i = 0; i < outBufLen; i++)
{
printf("%02x ", outBuf[i]);
}
printf("\n");

free(outBuf);

printf("in: %p\n", in);
printf("inLen: %u\n", inLen);
printf("outBufLen: %u\n", outBufLen);
printf("outLen1: %u\n", outLen1);
printf("outLen2: %u\n", outLen2);
printf("\n\n");
}

void decrypt_des_ede_cbc_pkcs(
unsigned char *out,		// 待解密数据
unsigned int   outLen,	// 待解密数据字节数
unsigned char *key,		// 密  钥，长度总是24字节
unsigned char *iv)		// 偏移量，长度总是08字节
{
printf("decrypt......\n\n");

unsigned char *inBuf;
unsigned int inBufLen, inLen1, inLen2;

/* 依据PKCS填充规则 */
inBufLen = (outLen/8 - 1) * 8;
inBuf = (unsigned char *)malloc(inBufLen);

EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_DecryptInit_ex(&ctx, EVP_des_ede3_cbc(), NULL, key, iv);
EVP_DecryptUpdate(&ctx, inBuf, &inLen1, out, outLen);
EVP_DecryptFinal_ex(&ctx, inBuf+inLen1, &inLen2);

unsigned int i;
for (i = 0; i < inBufLen; i++)
{
printf("%02x ", inBuf[i]);
}
printf("\n");

free(inBuf);

printf("out: %p\n", out);
printf("outLen: %u\n", outLen);
printf("inBufLen: %u\n", inBufLen);
printf("inLen1: %u\n", inLen1);
printf("inLen2: %u\n", inLen2);
printf("\n\n");
}

int main()
{
/* 加载算法 */

/* 密钥长度24字节 */
unsigned char key[]	= { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef,
0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef,
0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef };

/* 偏移量长度8字节 */
unsigned char iv []	= { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef };

/* 加密 */
unsigned char in [] = "test1280";
unsigned int  inLen = 8; // 不可strlen(in)，考虑到in中包含0x00字节会导致获取待加密数据长度错误
encrypt_des_ede_cbc_pkcs(in, inLen, key, iv);

/* 解密 */
unsigned char out[] = {	0x64, 0x5a, 0x6b, 0xd6, 0xbf, 0xf8, 0x36, 0xb2,
0x4f, 0xd1, 0x74, 0xf6, 0xe7, 0xf6, 0xaf, 0xdb };
unsigned int outLen = 16;// 不可strlen(out)
decrypt_des_ede_cbc_pkcs(out, outLen, key, iv);

return 0;
}


$gcc -o main main.c -lssl -lcrypto$ ./main
encrypt......

64 5a 6b d6 bf f8 36 b2 4f d1 74 f6 e7 f6 af db
in: 0x7fff77a7c910
inLen: 8
outBufLen: 16
outLen1: 8
outLen2: 8

decrypt......

74 65 73 74 31 32 38 30
out: 0x7fff77a7c900
outLen: 16
inBufLen: 8
inLen1: 8
inLen2: 0


man EVP_des_ede3_cbc 或者：
https://www.openssl.org/docs/man1.0.2/man3/EVP_des_ede3_cbc.html 有说：

If padding is enabled (the default) then EVP_EncryptFinal_ex() encrypts the “final” data, that is any data that remains in a partial block. It uses standard block padding (aka PKCS padding).

If padding is disabled then EVP_EncryptFinal_ex() will not encrypt any more data and it will return an error if any data remains in a partial block: that is if the total data length is not a multiple of the block size.

PKCS说明：

PKCS padding works by adding n padding bytes of value n to make the total length of the encrypted data a multiple of the block size. Padding is always added so if the data is already a multiple of the block size n will equal the block size. For example if the block size is 8 and 11 bytes are to be encrypted then 5 padding bytes of value 5 will be added.

#### 等价的，基于 java 实现 des ede3 cbc pkcs#5 算法，请参见：

https://blog.csdn.net/test1280/article/details/105255023

1.https://www.openssl.org/docs/man1.0.2/man3/EVP_des_ede3_cbc.html
2.https://www.openssl.org/docs/man1.0.2/man3/EVP_des_ede3_cbc.html#NOTES
3.https://blog.csdn.net/lrhui0903/article/details/39781623
4.https://stackoverflow.com/questions/9038298/java-desede-encrypt-openssl-equivalent
5.https://www.cnblogs.com/AloneSword/p/3479429.html

07-19 3939
06-22 2万+
08-15 1790
02-24 253
09-13 1万+
06-03 51
10-11 3596
11-28 878
05-16 56
06-22 4220
03-24 9398
01-12 2331
01-11 1万+
11-05