简体   繁体   English

将Windows CryptoAPI Salt和Hash转换为PHP

[英]Translate Windows CryptoAPI Salt and Hash to PHP

We have a legacy application that creates a Salt and Hash using the CryptoHashData function of the Windows CryptoAPI. 我们有一个旧版应用程序,该应用程序使用Windows CryptoAPI的CryptoHashData函数创建Salt和Hash。 We take a random byte string, apply the hash and then apply that hash to a second string of data using CryptoHashData again. 我们采用随机字节字符串,应用哈希,然后再次使用CryptoHashData将哈希应用于第二个数据字符串。 Here is the code. 这是代码。 A random key is hashed and then hashed again with the secret data. 随机密钥被散列,然后再与秘密数据一起散列。

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);

We have been able to recreate the first step on PHP by using the simple md5() function to hash the random byte string baKeyRandom. 通过使用简单的md5()函数对随机字节字符串baKeyRandom进行哈希处理,我们已经能够在PHP上重新创建第一步。 The value returned by this hash matches exactly the first hash on the ::CryptoHashData. 此哈希返回的值与:: CryptoHashData上的第一个哈希完全匹配。

$random = md5($random); 

matches exactly with 完全符合

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

What we haven't been able to figure out is how the CryptoAPI combines the first hash in the buffer with the second data string to being hashed with it. 我们还无法弄清楚CryptoAPI如何将缓冲区中的第一个哈希与第二个数据字符串组合在一起以进行哈希处理。
ie How do we recreate the second step of 即我们如何重新创建第二步

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

We've tried the most obvious methods of: 我们尝试了以下最明显的方法:

$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 of these methods match the values from CryptoHashData(random) + CryptoHashData(secret) 这些方法都不符合CryptoHashData(random)+ CryptoHashData(secret)中的值

Does anyone know how the CryptoHashData will combine the two values in the buffer that will then be hashed? 有谁知道CryptoHashData如何将缓冲区中的两个值组合在一起然后进行哈希处理? Has anyone recreated this CryptoAPI hash+salt method on other platforms that could be reproduced in PHP? 有没有人在其他平台上重新创建过这种可以用PHP复制的CryptoAPI hash + salt方法? Yes, we know this isn't secure and its not being used for passwords or PII. 是的,我们知道这是不安全的,并且不用于密码或PII。 We would like to move away from this old and insecure method, but we need take this interim step of translating the original encryption to PHP first for interoperability with the existing deployed systems. 我们希望摆脱这种古老而又不安全的方法,但是我们需要采取此过渡步骤,首先将原始加密转换为PHP,以实现与现有已部署系统的互操作性。 Any help or guidance would be appreciated. 任何帮助或指导,将不胜感激。

Here is the final working code based on accepted answer below. 这是基于下面公认答案的最终工作代码。

<?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();
?>

You cannot use md5() function in PHP for progressive updating of hash. 您不能在PHP中使用md5()函数来逐步更新哈希。 Chaining of hash algorithms are based on internal state of algorithm, not inputs. 哈希算法的链接基于算法的内部状态,而不是输入。 The internal state of md5 cannot be transferred when we use md5() method, so progressive update is not possible. 当我们使用md5()方法时,无法传递md5的内部状态,因此无法进行渐进式更新。

You need to use hash_init() , hash_update() , and hash_final() for stream hashing. 您需要使用hash_init()hash_update()hash_final()进行流哈希。 Here is an example: 这是一个例子:

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

This code result will be similar to your Windows API calls. 此代码结果将类似于您的Windows API调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM