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

在C++中解密AES加密字符串时出现冗余字符问题

AES解密后出现冗余字符的解决方法

我用C++的AES解密函数解密字符串时,得到了一些冗余字符。这套代码原本是为加密和解密原始字节编写的,以下是我的代码:

Python AES加密脚本

import sys
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import get_random_bytes
import hashlib

def encrypt_string(plaintext, key):
    iv = 16 * b'\x00'
    cipher = AES.new(hashlib.sha256(key).digest(), AES.MODE_CBC, iv)
    ciphertext = cipher.encrypt(pad(plaintext.encode(), AES.block_size))
    return ciphertext

KEY = get_random_bytes(16)

try:
    plaintext = input(">> ")
except:
    print("Input string needed!")
    sys.exit()

ciphertext = encrypt_string(plaintext, KEY)

print('AESkey[] = { 0x' + ', 0x'.join(hex(x)[2:] for x in KEY) + ' };')
print('payload[] = { ' + ', '.join(str(x) for x in ciphertext) + ' };')

C++解密函数

int AESDecrypt(char * payload, unsigned int payload_len, char * key, size_t keylen) {
        HCRYPTPROV hProv;
        HCRYPTHASH hHash;
        HCRYPTKEY hKey;

        if (!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)){
                return -1;
        }
        if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)){
                return -1;
        }
        if (!CryptHashData(hHash, (BYTE*)key, (DWORD)keylen, 0)){
                return -1;              
        }
        if (!CryptDeriveKey(hProv, CALG_AES_256, hHash, 0,&hKey)){
                return -1;
        }
        
        if (!CryptDecrypt(hKey, (HCRYPTHASH) NULL, 0, 0, payload, &payload_len)){
                return -1;
        }
  
        CryptReleaseContext(hProv, 0);
        CryptDestroyHash(hHash);
        CryptDestroyKey(hKey);
        
        return 0;
}

问题原因

冗余字符来自PKCS#7填充:Python加密时用pad()函数给明文添加了填充字节,确保长度符合AES块大小(16字节)要求,但C++解密后没有移除这些填充内容。

解决方法

解密完成后,手动移除PKCS#7填充即可。PKCS#7的规则是:填充字节的数值等于填充的长度(比如缺3字节就填充3个0x03)。

修改后的C++解密函数如下:

// 定义AES块大小,避免硬编码
#define AES_BLOCK_SIZE 16

int AESDecrypt(char * payload, unsigned int payload_len, char * key, size_t keylen) {
        HCRYPTPROV hProv;
        HCRYPTHASH hHash;
        HCRYPTKEY hKey;

        if (!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)){
                return -1;
        }
        if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)){
                return -1;
        }
        if (!CryptHashData(hHash, (BYTE*)key, (DWORD)keylen, 0)){
                return -1;              
        }
        if (!CryptDeriveKey(hProv, CALG_AES_256, hHash, 0,&hKey)){
                return -1;
        }
        
        if (!CryptDecrypt(hKey, (HCRYPTHASH) NULL, 0, 0, (BYTE*)payload, &payload_len)){
                return -1;
        }

        // 移除PKCS#7填充
        if (payload_len == 0) return -1;
        unsigned char pad_len = payload[payload_len - 1];
        // 验证填充合法性(可选但推荐,防止篡改或错误解密)
        if (pad_len > AES_BLOCK_SIZE || pad_len > payload_len) return -1;
        for (int i = payload_len - pad_len; i < payload_len; i++) {
                if (payload[i] != pad_len) return -1;
        }
        payload_len -= pad_len;
        // 给字符串添加结束符,确保C风格字符串正常使用
        payload[payload_len] = '\0';
  
        CryptReleaseContext(hProv, 0);
        CryptDestroyHash(hHash);
        CryptDestroyKey(hKey);
        
        return payload_len; // 返回实际明文长度,方便调用方处理
}

额外说明

  • 建议将payload参数改为BYTE*类型,避免字符类型的符号问题;
  • 填充验证步骤可以过滤非法的解密结果,提升安全性;
  • 如果处理的是二进制数据而非字符串,可以省略添加'\0'的步骤。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 17:27:51