首页 > 解决方案 > C 和 PHP 中的 AES 解密/加密

问题描述

所以这是我用作示例的代码

Aes128KeyLength = 128/8;

    //
    // Allocate Key buffer
    //

    Aes128Key = (PBYTE) HeapAlloc( GetProcessHeap(), 0, Aes128KeyLength);
    if( NULL == Aes128Key )
    {
        Status = STATUS_NO_MEMORY;
        ReportError(Status);
        goto cleanup;
    }

    //
    // Derive the AES 128 key from the password 
    // Using PBKDF2
    //

    //
    // Open an algorithm handle
    //

    Status = BCryptOpenAlgorithmProvider(
                                        &KdfAlgHandle,              // Alg Handle pointer
                                        BCRYPT_PBKDF2_ALGORITHM,    // Cryptographic Algorithm name (null terminated unicode string)
                                        NULL,                       // Provider name; if null, the default provider is loaded
                                        0);                         // Flags
    if( !NT_SUCCESS(Status) )
    {
        ReportError(Status);
        goto cleanup;
    }


    //
    // Create a key handle to the password
    //

    Status = BCryptGenerateSymmetricKey(
                                        KdfAlgHandle,               // Algorithm Handle 
                                        &Aes128PasswordKeyHandle,   // A pointer to a key handle
                                        NULL,                       // Buffer that recieves the key object;NULL implies memory is allocated and freed by the function
                                        0,                          // Size of the buffer in bytes
                                        (PBYTE)Aes128Password,      // Buffer that contains the key material
                                        sizeof (Aes128Password),    // Size of the buffer in bytes
                                        0);                         // Flags
    if( !NT_SUCCESS(Status) )
    {
        ReportError(Status);
        goto cleanup;
    }


    //
    // Derive AES key from the password
    //

    Status = BCryptKeyDerivation(
                                        Aes128PasswordKeyHandle,    // Handle to the password key
                                        &PBKDF2Parameters,          // Parameters to the KDF algorithm
                                        Aes128Key,                  // Address of the buffer which recieves the derived bytes
                                        Aes128KeyLength,            // Size of the buffer in bytes
                                        &ResultLength,              // Variable that recieves number of bytes copied to above buffer  
                                        0);                         // Flags
    if( !NT_SUCCESS(Status) )
    {
        ReportError(Status);
        goto cleanup;
    }

hash_pbkdf2在 PHP 端使用函数来做同样的事情。在 PHP 中我添加了echo hash_pbkdf2("sha256","PASSWORD", $salt,1000, 16, TRUE);

这是什么原因?我已经尝试了我在网上找到的各种标准测试,但输出仍然不一样。我看不出我可能在哪里搞砸了。对于 C 代码中的迭代次数是 1000 以及 PHP 端的相同值。我传递给函数的所有值在 PHP 和 C 端都是相同的。但是 C 和 PHP 端的输出派生键不一样?我做错了什么还是我应该注意一些能力问题?

标签: phpcwinapicryptographycryptoapi

解决方案


除了您提到的迭代之外,盐还会影响生成的密钥。

下面我在 php 和 C++(示例)中使用相同的 salt 'a'/ 。0x61

<?php
$password = "PASSWORD";
$iterations = 1000;
$salt = 'a'; //0x61

$hash = hash_pbkdf2("sha256", $password, $salt, $iterations, 16);
echo $hash;
?>

因此,如果您使用与 CipherEncryptionDecryption.cpp 中的盐值相同的盐值,您将得到相同的结果。

static const
BYTE Salt [] =
{
    0x61
};

两者都给了我结果:

32f8b5d8c4d1aa1fbb39a0a33338ccb1


推荐阅读