2016-09-03 16 views
2

ユーザーとそのパスワードを持つデータベースがDjango(pbkdf2)で保護されているため、問題があります。したがって、 '123'は次のようになります。PHPのDjangoパスワード

pbkdf2_sha256$20000$MflWfLXbejfO$tNrjk42YE9ZXkg7IvXY5fikbC+H52Ipd2mf7m0azttk= 

このパスワードをPHPプロジェクトで使用する必要があります。これらのパスワードを比較する方法はありません。

+0

私は強く同意します@Sayse - 彼はdjangoをPHPに置き換えているように聞こえるので、答えは "両方を実行しないでください" – Fitblip

答えて

4

pbkdf2_sha256$20000$MflWfLXbejfO$tNrjk42YE9ZXkg7IvXY5fikbC+H52Ipd2mf7m0azttk=

これを打破するのをしてみましょう。 $はセパレータです:

  • pbkdf2_sh256はすなわちhash_pbkf2('sha256', ...)
  • 20000、PBKDF2-SHA256を意味反復回数
  • MflWfLXbejfOは塩
  • tNrjk42YE9ZXkg7IvXY5fikbC+H52Ipd2mf7m0azttk=の可能性が高いハッシュであるされています。

これは、PHPからハッシュを検証するために必要なすべての情報です。あなただけの必要があります。

  1. hash_pbkdf2()格納されている1つ

この機能で生成されたハッシュを比較するために、ユーザー

  • hash_equals()によって提供されたパスワードから新しいハッシュを生成するために(PHPを動作するはずです7+ ):

    /** 
    * Verify a Django password (PBKDF2-SHA256) 
    * 
    * @ref http://stackoverflow.com/a/39311299/2224584 
    * @param string $password The password provided by the user 
    * @param string $djangoHash The hash stored in the Django app 
    * @return bool 
    * @throws Exception 
    */ 
    function django_password_verify(string $password, string $djangoHash): bool 
    { 
        $pieces = explode('$', $djangoHash); 
        if (count($pieces) !== 4) { 
         throw new Exception("Illegal hash format"); 
        } 
        list($header, $iter, $salt, $hash) = $pieces; 
        // Get the hash algorithm used: 
        if (preg_match('#^pbkdf2_([a-z0-9A-Z]+)$#', $header, $m)) { 
         $algo = $m[1]; 
        } else { 
         throw new Exception(sprintf("Bad header (%s)", $header)); 
        } 
        if (!in_array($algo, hash_algos())) { 
         throw new Exception(sprintf("Illegal hash algorithm (%s)", $algo)); 
        } 
    
        $calc = hash_pbkdf2(
         $algo, 
         $password, 
         $salt, 
         (int) $iter, 
         32, 
         true 
        ); 
        return hash_equals($calc, base64_decode($hash)); 
    } 
    

    デモ:https://3v4l.org/WbTpW

    レガシーPHP 5サポートが必要な場合は、string接頭辞を削除し、: boolを関数定義から削除すると、PHP 5.6で動作するようになります。 5.6より前のバージョンのPHPの下位互換性を追加しようと勧めていません。あなたがこのような状況におかれたら、you should update your server software instead

  • +1

    'hash_equals'を使うための小道具 - 常時比較は*安全な方法。 PBKDF2の出力は入力から推測できないため、通常の文字列比較を安全に使用できますが、タイミング攻撃に影響を与える方法はないため、サイドチャネルにするべきではありません)。 – Fitblip

    +0

    正しいですが、 'hash_equals()'を使用しないパスワードハッシュ関数には実用的な攻撃はありません。私は一貫性と私のコードスニペットを参照する人々の良い習慣を確立するためにそうする。 :) –

    +1

    これは確かに物事について行く方法です:)。常に一定の時間比較を行うことは決して痛くない(ハッシュのために数サイクル続く)。 – Fitblip