У нас есть устаревшее приложение, которое создает 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();
?>
Вы не можете использовать 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.
Других решений пока нет …