Перевести Windows CryptoAPI Salt and Hash для переполнения стека

У нас есть устаревшее приложение, которое создает 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();
?>

2

Решение

Вы не можете использовать 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.

3

Другие решения

Других решений пока нет …