web-dev-qa-db-ja.com

PHPでNTLMv2ハッシュを生成するアルゴリズム

私は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

誰かが正しいアルゴリズムを提案できますか?

2
asim-ishaq

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 ) );
}
3
asim-ishaq

おそらくエンコードの問題があります:

  • ハッシュ関数はbytesを処理することに注意してください。ただし、文字列には文字または16進数が含まれる場合があります。たとえば、あなたの$client_challenge0101で始まる文字列であり、おそらくshouldが2バイトの値1で始まることを意味しますが、ハッシュ関数がそれを取得した可能性があります4文字のエンコードとして、おそらく4バイトの値48、49、48および49(数字0および1のASCIIコード)。

  • 少なくとも最初のMD4はリトルエンディアンUTF-16でエンコードされたパスワードに対して計算する必要があり、mhash()があなたのためにそれを行うことを私は真剣に疑っています。

PHPはこれらの問題については十分に規定されていないため、最初にバイトがバイトであり、エンコーディングの問題を明示的に処理できる言語でコードをプロトタイプ化することをお勧めします。 JavaとC#が思い浮かびます。このような言語で正しい値を計算する関数を取得したら、PHPコードと比較する中間結果を出力して、問題を特定できるようにすることができます。

2
Tom Leek