Перевести Windows CryptoAPI Salt and Hash на PHP - PullRequest
0 голосов
/ 24 декабря 2018

У нас есть устаревшее приложение, которое создает Salt and Hash с помощью функции CryptoHashData в Windows CryptoAPI.Мы берем случайную байтовую строку, применяем хеш, а затем применяем этот хеш ко второй строке данных, снова используя CryptoHashData.Вот кодСлучайный ключ хешируется, а затем снова хешируется с секретными данными.

BYTE baKeyRandom[10] = {87,253, ...}; 
pszSecret = 'ABCDEF-G...';
::CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hSaveHash); 
::CryptHashData(hSaveHash, baKeyRandom, (DWORD)sizeof(baKeyRandom), 0);
::CryptHashData(hSaveHash, (LPBYTE)T2CW(pszSecret), (DWORD)_tcslen(pszSecret) * sizeof(WCHAR), 0);

Мы смогли воссоздать первый шаг в PHP с помощью простой функции md5 () для хеширования случайной строки байтов baKeyRandom.Значение, возвращаемое этим хешем, точно соответствует первому хешу в :: CryptoHashData.

$random = md5($random); 

точно совпадает с

::CryptHashData(hSaveHash, baKeyRandom, (DWORD)sizeof(baKeyRandom), 0);

Что мы не смогли выяснить, так это какCryptoAPI объединяет первый хеш в буфере со второй строкой данных для хеширования вместе с ним.
т.е. как мы воссоздаем второй шаг

::CryptHashData(hSaveHash, (LPBYTE)T2CW(pszSecret), (DWORD)_tcslen(pszSecret) * sizeof(WCHAR), 0);

Мы попробовали наиболее очевидные методы:

$random = md5($random); followed by any of the below
$key = md5($random.$secret); 
$key = md5($secret.$random); 
$key = md5($random.md5($secret)); 
$key = md5(md5($secret).$random);

Ни один из этих методов не соответствует значениям из CryptoHashData (random) + CryptoHashData (secret)

Кто-нибудь знает, как CryptoHashData объединит два значения в буфере, который затемхешироваться?Кто-нибудь воссоздал этот метод CryptoAPI hash + salt на других платформах, которые можно воспроизвести на PHP?Да, мы знаем, что это небезопасно и не используется для паролей или PII.Мы хотели бы отойти от этого старого и небезопасного метода, но нам нужно сделать этот промежуточный шаг - сначала перевести оригинальное шифрование на PHP для взаимодействия с существующими развернутыми системами.Буду признателен за любую помощь или руководство.

Вот окончательный рабочий код, основанный на принятом ответе ниже.

<?php
function main(){
    $random = pack('c*', 22,194,253,.......); 
    $secret = pack('c*', 22,194,253,.......);

    $hash = hash_init("md5");
    hash_update($hash, $random);
    hash_update($hash, $secret);
    print(hash_final($hash));
}

main();
?>

1 Ответ

0 голосов
/ 25 декабря 2018

Вы не можете использовать функцию md5() в PHP для прогрессивного обновления хеша. Цепочка алгоритмов хеширования основана на внутреннем состоянии алгоритма, а не на входах. Внутреннее состояние md5 не может быть передано при использовании метода md5(), поэтому последовательное обновление невозможно.

Вам необходимо использовать hash_init(), hash_update() и hash_final() для хеширования потока.Вот пример:

<?php
$hash = hash_init("md5");
$data1="ABCD";
hash_update($hash, $data1);
$data2="ABCD";
hash_update($hash, $data2);
print(hash_final($hash));
?>

Этот код будет похож на ваши вызовы Windows API.

...