将 Windows CryptoAPI Salt 和 Hash 翻译成 PHP

Translate Windows CryptoAPI Salt and Hash to PHP

我们有一个遗留应用程序,它使用 Windows CryptoAPI 的 CryptoHashData 函数创建 Salt 和 Hash。我们获取一个随机字节字符串,应用哈希,然后再次使用 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);

通过使用简单的 md5() 函数对随机字节字符串 baKeyRandom 进行哈希处理,我们已经能够在 PHP 上重新创建第一步。此散列返回的值与 ::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);

None 这些方法匹配 CryptoHashData(random) + CryptoHashData(secret)

的值

有谁知道 CryptoHashData 如何将缓冲区中的两个值组合起来然后进行哈希处理?是否有人在其他平台上重新创建了可以在 PHP 中重现的 CryptoAPI hash+salt 方法?是的,我们知道这不安全,也不会用于密码或 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();
?>

您不能使用 PHP 中的 md5() 函数来逐步更新哈希。 散列算法的链接基于算法的内部状态,而不是输入。 当我们使用 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 调用。