PHP加密和Windows解密

Mic*_*kis 14 php c++ encryption aes

我被卡住了.似乎PHP完成的AES加密无法在Windows中解密.

PHP代码:

$encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128,"12345678", "test", MCRYPT_MODE_CBC));
Run Code Online (Sandbox Code Playgroud)

Windows代码:"s"具有从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);
}
Run Code Online (Sandbox Code Playgroud)

可能有什么不对?

Ros*_*nko 9

您提供的信息不足以说明,但我认为您的问题是密钥长度.

在PHP代码中,您将"12345678"作为键传递.AES128的密钥长度为128位或16字节.PHP 填充剩余的零字节,如mcrypt_encrypt文档中所述.

在C++代码中,只将指向密钥缓冲区的指针传递给Decrypt函数.但是然后你将16个字节从它复制到密钥BLOB:

aes_blob128.keySize = 16;
memcpy(aes_blob128.bytes, key, 16);
Run Code Online (Sandbox Code Playgroud)

那么如果你把你的函数称为:

char dest[16];
bool result = Decrypt(string_from_php,"12345678",dest);
Run Code Online (Sandbox Code Playgroud)

在将"12345678"常量复制到密钥blob并作为实际密钥传递给CryptImportKey之后,恰好存在于内存中的8个字节.因此,C代码和PHP代码中的密钥实际上是不同的,并且由于填充错误,解密将失败.