在 Cpp 中解密 AES 加密字符串时出现错误

问题描述 投票:0回答:1

当我使用解密函数解密字符串时,我得到了一些冗余字符。实际上,这段代码是为了加密和解密原始字节而编写的。

这是我的代码。

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) + ' };')

CPP解密功能:

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;
}
python c++ cryptography runtime-error aes
1个回答
0
投票

在调用

CryptDecrypt()
时不会删除填充,因为您尚未将第三个参数设置为
TRUE
。因此你的电话应该

if (!CryptDecrypt(hKey, (HCRYPTHASH) NULL, TRUE, 0, payload, &payload_len)){
        return -1;
}

或者,如果你坚持避免使用信息常量,

if (!CryptDecrypt(hKey, (HCRYPTHASH) NULL, 1, 0, payload, &payload_len)){
        return -1;
}

顺便说一句,我在Microsoft CryptDecrypt文档中注意到描述第三个参数功能的备注部分包含一个严重错误。它说当第三个参数为

TRUE
时:

如果密钥是分组密码密钥,则数据将被填充为的倍数 密码的块大小。要查找密码的块大小,请使用 CryptGetKeyParam 获取密钥的 KP_BLOCKLEN 值。

这实际上是在加密上发生的事情,而不是解密。微软只是复制并粘贴了

CryptEncrypt
的文档,并未能更改这部分内容。实际发生的情况是,如果第三个参数是
TRUE
,则填充会 removed,

© www.soinside.com 2019 - 2024. All rights reserved.