我試圖解密 - 使用C++中的Microsoft CryptoAPI - 使用PHP中的mcrypt_encrypt加密的短消息。 php的行是: mcrypt_encrypt(MCRYPT_RIJNDAEL_256,$ key,$ msg,MCRYPT_MODE_CBC);加密解密時使用AES 256(MS CryptoAPI)時出現錯誤的數據錯誤
其中$ key和$ msg是字符串。
在C++中我有鑰匙,我的解密功能如下:
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++的關鍵/和/或消息傳遞......如果你同意你可以給我一個關於如何確保我在PHP中使用的字符串與在C + +的(在字節級?)
編輯2 - 我改變了我的在php中使用二進制流(使用pack),然後我從這裏實現了AES vs Rijndael的解決方法(?):http://kix.in/2008/07/22/aes-256-using-php-mcrypt/我最終用CryptDecrypt解密了我的PHP消息......問題在於它仍然失敗 - 即使輸出包含解密的文本。任何想法爲什麼會發生這種情況?
確保您在通道的兩端都使用相同的填充模式。 –