私はPHP関数を開発して、サーバーとクライアントのチャレンジ、ドメイン、アカウント、およびパスワードを提供することによってNTLMv2ハッシュを計算します。結果のハッシュは正しくないようです。誰かが正しいことを教えてくれますか?仕方:
PHP言語のアルゴリズム:
function GenerateNTMLv2($password, $account, $domain, $client_challenge, $server_challenge) {
$hash = mhash(MHASH_MD4, $password);
$hash = mhash(MHASH_MD5, strtoupper($account) . $domain, $hash);
$hash = mhash(MHASH_MD5, $client_challenge . $server_challenge, $hash);
return strtoupper(bin2hex($hash));
}
次のパラメーターを指定しました。
$password='asim3347';
$client_challenge = '0101000000000000DF5ED1178FBACE012FDEE788AA2574CE0000000002001200430041004E00440059004C0041004E00440001001200430041004E00440059004C0041004E00440004001200630061006E00640079006C0061006E00640003001200630061006E00640079006C0061006E006400060004000300000007000800DF5ED1178FBACE0108003000300000000000000001000000002000004C60DD0226C932C69BAF540769C9E4DA53ABF77A8D56DBA0F9AA214EEEBB30AE0A001000000000000000000000000000000000000900240063006900660073002F003100390032002E003100360038002E0030002E003200320038000000000000000000';
$server_challenge = 'FFC7C728CAAC8BE8';
$domain = 'SOFTECH';
$account = 'asim';
この関数は次のNTLMv2ハッシュを返します。48335EFCA9A07EA12B9EBBC2AEE30C8E
HASHは次のようにする必要があります:780B32F46FA60CE1431264A525B0D6
誰かが正しいアルゴリズムを提案できますか?
PHPの正しいアルゴリズムを整理しました。貢献してくれてありがとう。コードは次のとおりです。
function GenerateNTMLv2($password, $account, $domain, $client_challenge, $server_challenge) {
$unicode_password= iconv ( 'UTF-8', 'UTF-16LE', $password );
$NTLM_Key = mhash ( MHASH_MD4, $unicode_password);
$NTLM_Hash = mhash ( MHASH_MD5, iconv ( 'UTF-8', 'UTF-16LE', strtoupper ( $account ) . $domain ), $NTLM_Key );
$NTLM_Chal_Hash = mhash ( MHASH_MD5, pack ( "H*", $server_challenge . $client_challenge ), $NTLM_Hash );
return strtoupper ( bin2hex ( $NTLM_Chal_Hash ) );
}
おそらくエンコードの問題があります:
ハッシュ関数はbytesを処理することに注意してください。ただし、文字列には文字または16進数が含まれる場合があります。たとえば、あなたの$client_challenge
は0101
で始まる文字列であり、おそらくshouldが2バイトの値1で始まることを意味しますが、ハッシュ関数がそれを取得した可能性があります4文字のエンコードとして、おそらく4バイトの値48、49、48および49(数字0および1のASCIIコード)。
少なくとも最初のMD4はリトルエンディアンUTF-16でエンコードされたパスワードに対して計算する必要があり、mhash()
があなたのためにそれを行うことを私は真剣に疑っています。
PHPはこれらの問題については十分に規定されていないため、最初にバイトがバイトであり、エンコーディングの問題を明示的に処理できる言語でコードをプロトタイプ化することをお勧めします。 JavaとC#が思い浮かびます。このような言語で正しい値を計算する関数を取得したら、PHPコードと比較する中間結果を出力して、問題を特定できるようにすることができます。