将Windows CryptoAPI Salt和Hash转换为PHP

时间:2018-12-24 17:02:35

标签: php hash cryptography salt cryptoapi

我们有一个旧版应用程序,该应用程序使用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);

这些方法都不匹配CryptoHashData(随机)+ CryptoHashData(秘密)中的值

有人知道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();
?>

1 个答案:

答案 0 :(得分:3)

您不能在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调用。