PHP Encrypt and Windows Decrypt

aes, c++, encryption, php

Solution

The information you provided is not enough to say for certain but I think that your problem is the key length.

In PHP code you pass "12345678" as a key. And AES128 has a key length of 128bit or 16 bytes. PHP pads the remaining with zero bytes, as stated in the documentation on mcrypt_encrypt.

In the C++ code you pass only the pointer to your key buffer to Decrypt function. But then you copy 16 bytes from it to the key BLOB:

aes_blob128.keySize = 16;
memcpy(aes_blob128.bytes, key, 16);

Then if you call your function like:

char dest[16];
bool result = Decrypt(string_from_php,"12345678",dest);

than the 8 bytes that happen to reside in memory after the "12345678" constant will be copied to the key blob and passed to CryptImportKey as an actual key. Thus the key in C and in PHP code would be actually different and the decryption will fail due to padding error.

Problem

I 'm stuck. It seems that AES encryption done by PHP cannot be decrypted in windows. PHP code: ``` $encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128,"12345678", "test", MCRYPT_MODE_CBC)); ``` Windows Code: "s" has the string which is created by the above response after converting back from base64. ``` bool Decrypt(char* s,char* key,char* dest) { // Create the crypto provider context. HCRYPTPROV hProvider = NULL; if (!CryptAcquireContext(&hProvider, NULL, // pszContainer = no named container MS_ENH_RSA_AES_PROV, // pszProvider = default provider PROV_RSA_AES, 0)) return false; // Construct the blob necessary for the key generation. aes128keyBlob aes_blob128; aes_blob128.header.bType = PLAINTEXTKEYBLOB; aes_blob128.header.bVersion = CUR_BLOB_VERSION; aes_blob128.header.reserved = 0; aes_blob128.header.aiKeyAlg = CALG_AES_128; aes_blob128.keySize = 16; memcpy(aes_blob128.bytes, key, 16); HCRYPTKEY hKey = NULL; if (!CryptImportKey(hProvider, (BYTE*)(&aes_blob128), sizeof(aes_blob128), NULL, // 0, // &hKey)) { ... } // Set Mode DWORD dwMode = CRYPT_MODE_CBC; CryptSetKeyParam( hKey, KP_MODE, (BYTE*)&dwMode, 0 ); DWORD length = 16; BOOL X = CryptDecrypt(hKey, NULL, // hHash = no hash TRUE, // Final 0, (BYTE*)s, &length); //int le = GetLastError(); memcpy(dest,s,16); CryptDestroyKey(hKey); CryptReleaseContext(hProvider, 0); } ``` What could be wrong?

Original source