gpt4 book ai didi

c++ - 使用 AES 256 (MS CryptoAPI) 时 CryptDecrypt 出现错误数据错误

转载 作者:太空宇宙 更新时间:2023-11-04 12:15:33 25 4
gpt4 key购买 nike

我正在尝试解密 - 在 C++ 中使用微软的 CryptoAPI - 在 PHP 中使用 mcrypt_encrypt 加密的短消息。 php行是: mcrypt_encrypt( MCRYPT_RIJNDAEL_256, $key, $msg, MCRYPT_MODE_CBC);

$key 和 $msg 是字符串。

在 C++ 中我有 key ,我的解密函数如下所示:

bool decrypt( const unsigned char* input_buffer,
const size_t& input_size,
const unsigned char* key,
const size_t& key_size,
unsigned char* output_buffer,
DWORD* out_size)
{
Log(L"START init_crypto");

bool ret = false;
HCRYPTKEY hKey = NULL;
HCRYPTPROV hCryptProv = NULL;
DWORD dwDataLen = 0;

// Attempt to acquire a handle to the crypto provider for AES
if(0 == CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT) ){//PROV_RSA_AES
Log(L"CryptAcquireContext failed with code %ld", GetLastError());
goto end;
}

// key creation based on
// http://mirror.leaseweb.com/NetBSD/NetBSD-release-5-0/src/dist/wpa/src/crypto/crypto_cryptoapi.c
struct {
BLOBHEADER hdr;
DWORD len;
BYTE key[32];
} key_blob;

key_blob.hdr.bType = PLAINTEXTKEYBLOB;
key_blob.hdr.bVersion = CUR_BLOB_VERSION;
key_blob.hdr.reserved = 0;
key_blob.hdr.aiKeyAlg = CALG_AES_256;
key_blob.len = 32;//key_size;

memset(key_blob.key, '\0', sizeof(key_blob.key));

assert(key_size <= sizeof(key_blob.key));
CopyMemory(key_blob.key, key, min(key_size, sizeof(key_blob.key)));

if (!CryptImportKey( hCryptProv,
(BYTE *)&key_blob,
sizeof(key_blob),
0,
CRYPT_EXPORTABLE,
&hKey)){
Log(L"Error in CryptImportKey 0x%08x \n", GetLastError());
goto free_context;
}
else{
//---------------------------
// Set Mode
DWORD dwMode = CRYPT_MODE_CBC;
if(!CryptSetKeyParam( hKey, KP_MODE, (BYTE*)&dwMode, 0 )){
// Handle error
Log(L"Cannot set the cbc mode for decryption 0x%08x \n", GetLastError());
goto free_key;
}

//----------------------------
// Set IV
DWORD dwBlockLen = 0;
DWORD dwDataLen = sizeof(dwBlockLen);
if (!CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE *)&dwBlockLen, &dwDataLen, 0)){
// Handle error
Log(_USTR("Cannot get the block length 0x%08x \n"), GetLastError());
goto free_key;
}
dwBlockLen /= 8;
BYTE *pbTemp = NULL;
if (!(pbTemp = (BYTE *)LocalAlloc(LMEM_FIXED, dwBlockLen))){
// Handle error
Log(L"Cannot allcoate the IV block 0x%08x \n", GetLastError());
goto free_key;
}
memset(pbTemp, '\0', dwBlockLen);
if (!CryptSetKeyParam(hKey, KP_IV, pbTemp, 0)){
// Handle error
Log(L"Cannot set the IV block 0x%08x \n", GetLastError());
LocalFree(pbTemp);
goto free_key;
}

LocalFree(pbTemp);
}

CopyMemory(output_buffer, input_buffer, min(*out_size, input_size));
*out_size = input_size;

if (!CryptDecrypt(hKey, NULL, TRUE, 0, output_buffer, out_size)){
Log(L"CryptDecrypt failed with code %ld", GetLastError());
goto free_key;
}
else{
Log(L"Decryption...");
ret = true;
}
free_key:
if (hKey)
CryptDestroyKey( hKey );

free_context:
if (hCryptProv)
CryptReleaseContext(hCryptProv, 0);
end:
return ret;
}

我一直在 CryptDecrypt() 中收到“错误数据”错误...我可能遗漏了一些明显的东西 - 如果是这样,请帮忙。

编辑 - 为了找出问题的原因,我用以下代码替换了 CryptDecrypt 之前的两行(CopyMemory 内容):....

 strcpy((char*)output_buffer, "stuff");
DWORD plain_txt_len = strlen((char*)output_buffer);
if (!CryptEncrypt(hKey, NULL, TRUE, 0, output_buffer, &plain_txt_len, *out_size)){
Log(L"CryptEncrypt failed with code 0x%08x", GetLastError());
goto free_key;
}

...并且 CryptDecrypt 正在工作——这让我相信问题是从 php 到 C++ 的 key /和/或消息传输......如果你同意,你能给我一个关于如何确保我在 PHP 中使用的字符串的提示与C++中的相同(字节级别?)

编辑2——在我在 php 中更改二进制流中的字符串(使用 pack)之后,以及在我从这里实现 AES vs Rijndael 的解决方法(?)之后:http://kix.in/2008/07/22/aes-256-using-php-mcrypt/我终于让 CryptDecrypt 解密了我的 PHP 消息......问题是它仍然失败 - 即使输出包含解密的文本。关于为什么会发生这种情况的任何想法?

最佳答案

尝试在获取上下文时传递 NULL 而不是 CRYPT_VERIFYCONTEXT

关于c++ - 使用 AES 256 (MS CryptoAPI) 时 CryptDecrypt 出现错误数据错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7851402/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com