OpenSSL Triple-DES解密报错:最终块长度错误问题排查求助
问题分析与解决:Triple-DES解密时
wrong final block length错误 核心问题根源
- 密文长度计算错误:解密时使用
strlen((char*) ciphertext)获取密文长度,但密文是二进制数据,大概率包含'\0'字节,strlen()会在第一个'\0'处停止计数,导致传入解密函数的密文长度远小于实际值。 - 从运行输出的
BIO_dump结果看,实际密文长度为104字节,但strlen()计算的长度不足,使得解密时输入的密文长度不是Triple-DES块大小(8字节)的整数倍,触发wrong final block length错误。 - 额外问题:IV初始化
"1234567"只有7字节,Triple-DES要求8字节IV,虽会自动补'\0',但显式设置更严谨。
解决方案
关键修改
直接使用加密函数返回的ciphertext_len作为解密时的密文长度,不要用strlen()重新计算。同时修正IV的长度。
修改后的main函数代码
int main (void) { // set up timestamping struct timespec begin, end; // 显式定义24字节密钥和8字节IV,避免字符串自动补全的潜在问题 unsigned char key[24] = "0123456789abcdef01234567"; unsigned char iv[8] = "12345678"; int decryptedtext_len, ciphertext_len; const int LENGTH = 100; unsigned char plaintext[LENGTH]; unsigned char ciphertext[LENGTH + 200]; unsigned char decryptedtext[LENGTH + 1]; for(int i = 0; i < LENGTH - 1; i++) { plaintext[i] = 'A' + (rand() % 26); } plaintext[LENGTH - 1] = '\0'; // 加密明文,保存返回的密文长度 ciphertext_len = encrypt(plaintext, strlen((char*) plaintext), key, iv, ciphertext); printf("ciphertext is:\n"); BIO_dump_fp (stdout, (const char *)ciphertext, ciphertext_len); // 解密时直接使用加密得到的真实密文长度 decryptedtext_len = decrypt(ciphertext, ciphertext_len, key, iv, decryptedtext); // 添加终止符,确保可打印 decryptedtext[decryptedtext_len] = '\0'; // 输出解密结果 printf("decrypted text is:\n"); printf("%s\n", decryptedtext); return 0; }
通用注意事项
- 所有块密码(AES、Triple-DES、Camellia等)的密文都是二进制数据,处理时必须保存并传递实际字节长度,绝对不能使用字符串操作函数(如
strlen、strcpy)处理密文。 - 之前测试AES未出错只是偶然情况(密文恰好无
'\0'),这种做法不可靠,必须统一使用加密函数返回的长度值。
内容的提问来源于stack exchange,提问作者Spartacuz9er9er
相关产品推荐
相关产品推荐

