You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 17:34:56