-1

So this is the code I am using as an example

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;
    }

I am using hash_pbkdf2 function for the same thing on the PHP side. in PHP i added echo hash_pbkdf2("sha256","PASSWORD", $salt,1000, 16, TRUE);

what is the reason for this? I have tried various standard tests I found online but still the output is not the same. I cannot see where I am possibly messing up. For the C code from the the number of iterations is 1000 along with the same value on the PHP side. All the values I am passing to the function are the same on the PHP and C side. yet the output on the C and PHP side the derived key is not the same? What am I doing wrong or Is there some capability issue I should be aware of?

NTDLL
  • 21
  • 1
  • 3
  • 5
    It might help to read [mcve] then to edit your question to include code. – Dave S May 30 '19 at 23:59
  • bcrypt and PBKDF2 are different algorithms. – Peter Jun 02 '19 at 04:24
  • @Peter im not using bcrypt.... this is https://learn.microsoft.com/en-us/windows/desktop/api/bcrypt/ – NTDLL Jun 02 '19 at 04:49
  • A little hard to get motivated to investigate this without complete reproductions of both codes. – David Heffernan Jun 02 '19 at 07:53
  • @DavidHeffernan the code is literally the same on the PHP side and this is driving me crazy. I literally cannot see at all. What i am doing that is different. The salt i pass to the php function via hex2bin("salt from C code here"). Everything is the same I have no idea what in the world is going on here. – NTDLL Jun 02 '19 at 23:37
  • Well, we don't have all the code. – David Heffernan Jun 03 '19 at 07:11
  • @DavidHeffernan i had the code from https://github.com/Microsoft/Windows-classic-samples/blob/master/Samples/Security/CipherEncryptionDecryption/cpp/CipherEncryptionDecryption.cpp – NTDLL Jun 04 '19 at 04:40
  • @DavidHeffernan i looked today at the docs to see if there was any endian stuff going on. and still i have no idea wtf I am doing wrong... – NTDLL Jun 05 '19 at 00:24

1 Answers1

0

Except iterations you have mentioned, salt also effect the generated key.

The following I use the same salt 'a' / 0x61 in both php and C++ (sample).

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

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

So if you use the same salt value with the one in CipherEncryptionDecryption.cpp you will get the same result.

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

Both give me the result:

32f8b5d8c4d1aa1fbb39a0a33338ccb1

Rita Han
  • 9,574
  • 1
  • 11
  • 24
  • I have tried using the same salt value and the same password. it still does not give the same result. the 20 also should be 16 no? I have tried setting both of them constant values. I have tried generating the salt and copying it to the C code but still no luck. What am I doing wrong here? Is there something internal that is different between the KDF hash algos? – NTDLL May 31 '19 at 16:39
  • anyone have any idea? i still have this issue – NTDLL Jun 02 '19 at 02:18
  • @NTDLL Please check my update answer and have a try. – Rita Han Jun 05 '19 at 08:47