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

C语言中用OpenSSL库实现3DES CBC解密遇密钥长度异常求助

解决3DES CBC解密16字节密钥失效的问题

你遇到的核心问题是单DES的密钥调度逻辑无法适配16字节的双密钥3DES场景——16字节密钥属于双密钥3DES(2TDEA),需要用OpenSSL专门的3DES EDE(Encrypt-Decrypt-Encrypt)模式接口处理,而非单DES的流程。

问题根源

你当前代码用的是DES_key_schedule(单DES密钥调度),但16字节密钥对应的是双密钥3DES:加密时执行K1加密 → K2解密 → K1加密,解密时则是K1解密 → K2加密 → K1解密。单DES的处理逻辑完全不匹配这个三次操作的流程,自然会导致解密结果错误。

修改后的解密函数示例

下面是适配16字节双密钥3DES CBC解密的代码:

#include <openssl/des.h>
#include <string.h>

int CBC_3Des_Decrypt(unsigned char *data, int data_len, unsigned char *okey, unsigned char *out_data, int *out_len) {
    // 双密钥3DES需要两个独立的密钥调度
    DES_key_schedule ks1, ks2;
    DES_cblock ivec = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // 必须与加密时的IV完全一致
    DES_cblock key1, key2;
    int ret = -1;

    // 1. 拆分16字节密钥为两个8字节DES密钥
    if (strlen((char*)okey) != 16) {
        // 密钥长度不符合双密钥3DES要求,可根据需求扩展兼容8/24字节
        return ret;
    }
    memcpy(key1, okey, 8);
    memcpy(key2, okey + 8, 8);

    // 2. 设置密钥调度(自动调整奇偶校验并检查有效性)
    if (DES_set_key_checked(&key1, &ks1) != 0 || DES_set_key_checked(&key2, &ks2) != 0) {
        // 密钥无效(奇偶位错误等),若确认密钥合法可改用DES_set_key_unchecked跳过检查
        return ret;
    }

    // 3. 执行双密钥3DES CBC解密(EDE2模式)
    // 注意:输入data_len必须是8字节的倍数,3DES块大小固定为8字节
    *out_len = data_len;
    DES_ede2_cbc_encrypt(data, out_data, data_len, &ks1, &ks2, &ivec, DES_DECRYPT);

    // 4. 去除PKCS#7填充(如果加密时使用了填充)
    // 假设最后一个字节为填充长度,比如缺n字节就填充n个0x0n
    unsigned char pad_len = out_data[*out_len - 1];
    if (pad_len > 0 && pad_len <= 8) {
        *out_len -= pad_len;
        out_data[*out_len] = '\0'; // 确保字符串正常结束
    }

    ret = 0;
    return ret;
}

关键注意事项

  • 多密钥长度兼容:如果需要同时支持8字节(单DES)、16字节(双密钥3DES)、24字节(三密钥3DES),可增加长度判断分支:
    • 8字节:使用单DES的DES_ncbc_encrypt
    • 16字节:使用DES_ede2_cbc_encrypt
    • 24字节:使用DES_ede3_cbc_encrypt(拆分3个8字节密钥)
  • IV一致性:加密和解密必须使用完全相同的初始化向量(IV),否则解密结果会完全混乱。如果加密时IV不是全0,要同步传入解密函数。
  • 填充处理:3DES要求输入数据长度是8字节的倍数,加密时通常用PKCS#7填充补足长度,解密后必须去除填充才能得到原始明文。
  • 密钥奇偶校验:DES密钥的第8位是奇偶校验位,DES_set_key_checked会自动检查并调整;若密钥是外部传入的已处理过奇偶位的合法密钥,可改用DES_set_key_unchecked跳过检查。

内容的提问来源于stack exchange,提问作者Majid Hajibaba

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:33:01