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

WinAPI C++ AES-256-CBC加密后OpenSSL解密报块长度错误问题

WinAPI AES-256-CBC加密后OpenSSL解密失败问题修复

你代码里存在4个直接导致解密失败的错误,和字节序、加密算法兼容性无关:

  • 无意义的全密文反转操作
    WinAPI AES加密输出的密文字节流本身就是标准网络序(大端),和OpenSSL的输入要求完全一致,你调用ReverseStream把整个密文完全倒序,直接破坏了密文块顺序和块对齐规则,是触发wrong final block length错误的核心原因。
  • 加密接口调用逻辑错误
    你两次调用CryptEncrypt时长度参数使用混乱:第一次调用查询所需缓冲区大小时拿到的是预估最大长度,第二次实际加密完成后返回的dwBufSize2才是真实密文长度,你写文件时用了预估长度dwBufSize,会把缓冲区里未初始化的垃圾值一并写入文件,导致密文长度和内容异常。同时你用StrCpyA拷贝明文到加密缓冲区,会额外在明文末尾写入1字节的字符串结束符\0,导致实际加密的明文比预期多1字节,填充逻辑异常。
  • 文件写入逻辑笔误
    你判断文件句柄有效性时用的变量是ResList,实际调用WriteFile时传入的句柄是res,两个变量不统一的情况下,要么写文件完全失败,要么写入到错误的句柄,生成的encrypted.txt内容本身就是损坏的。
  • 密钥Blob拷贝存在越界风险
    你用StrCpyA拷贝密钥到AESBlob.szBytes时,会自动在32字节密钥后追加1字节结束符,容易造成结构体内存越界,覆盖相邻字段值。

修复步骤

  1. 直接删除ReverseStream相关逻辑,加密完成后直接使用pBuf中存储的原始密文写文件即可,不需要做任何字节序转换。
  2. 替换所有StrCpyA的明文、密钥、IV拷贝逻辑为memcpy,严格按照实际长度拷贝,避免自动追加结束符:
// 替换密钥拷贝
memcpy(AESBlob.szBytes, szKey, DEFAULT_AES_KEY_SIZE);
// 替换明文拷贝
memcpy(pBuf, szPlainText, dwPlainSize);
  1. 修正文件写入逻辑,统一文件句柄变量,写文件时使用第二次加密返回的真实密文长度:
// 统一句柄变量,示例用hFile代替你混写的res/ResList
if (hFile != INVALID_HANDLE_VALUE)
{
    WriteFile(
        hFile,
        pBuf,
        dwBufSize2, // 用真实密文长度,不要用预估长度
        &bytesWritten,
        NULL);
    CloseHandle(hFile);
}
  1. 修正OpenSSL解密命令,直接传入原始密钥和IV时不需要走密钥派生,加-pbkdf2参数即可消除版本警告:
openssl aes-256-cbc -d -nosalt -pbkdf2 \
-K "3030313132323333343435353636373738383939303031313232333334343535" \
-iv "34343535363637373838393930303131" \
-in encrypted.txt -out secrets.txt

注:WinAPI的AES实现默认使用PKCS7填充,和OpenSSL默认填充规则完全一致,不需要额外加-nopad参数。

修复后本地WinAPI解密和Linux端OpenSSL解密都可以正常得到原始明文。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 11:03:25