0

新しいユーザーを登録し、次のハッシュ方法を使用してユーザー名、パスワード、およびソルトをDBに保存しました。

    if(isset($_POST['register']))
    {
    $password = $_POST['password']

    function sanitize($data)
    {
        $data=trim($data);
        $data=htmlspecialchars($data);
        $data=mysql_real_escape_string($data);
        return $data;
    }

    $password = sanitize($password);

    function createSalt()
    {
        $salt = bin2hex(mcrypt_create_iv(32,MYCRYPT_DEV_URANDOM));
        $hash = hash("sha256", $salt);
        $final = $salt.$hash;
        return $final;
    }

    $hashedPassword = hash("sha256", $password);
    $salt = createSalt();
    $hashedPassword = hash("sha256", $hashedPassword.$salt);

    $query = sprintf("INSERT INTO users(username, password, salt) VALUES('%s','%s','%s')",$username, $hashedPassword, $salt);
}

その後、login.phpを試しているときに、登録時に保存したものと同じパスワードを入力し、以下のコードを使用して、入力したパスワードがDBのパスワードと同じかどうかを確認します。

if(isset($_POST['login']]))
{
            $password = $_POST['password']

    function sanitize($data)
    {
        $data=trim($data);
        $data=htmlspecialchars($data);
        $data=mysql_real_escape_string($data);
        return $data;
    }

    function validateUser()
    {
        session_regenerate_id (); //this is a security measure
        $_SESSION['valid'] = 1;
        $_SESSION['username'] = $username;
    }

    $password = sanitize($password);

    $query = sprintf("SELECT * FROM users WHERE username = '%s'",$username);
    $sql = mysql_query($query);
    $count = mysql_num_rows($sql);

    $row = mysql_fetch_array($sql);

    if($count<1)
    {
        echo $count;
        unset($_POST['login']);
        header("location:login.php");
        exit;
    }

    $hash = hash("sha256", $password);
    $salt = $row['salt'];
    $hash = hash("sha256",$hash.$salt);

    echo $hash."<br />".$row['password']."<br /><br />";

    if($hash != $row['password'])
    {
        unset($_POST['login']);
        header("location:login.php");
        exit;   
    }
    else
    {
        validateUser();
        unset($_POST['login']);
        header("location:index.php");
        exit;   
    }
}

これらのパスワードは一致していません。このコードの何が問題になっているのか教えてください。

4

2 に答える 2

0

コードに問題はありません。

varchar値が低いため、データベースに格納されているsalt値は切り捨てられます。これは、salt列のvarchar値を200〜300に増やしてから、これを試してみてください。正常に実行されます。

これが結果を台無しにしていることを知ったとき、私は顔をしかめました。

ディン

于 2012-11-09T08:31:58.913 に答える
0

実際、これが機能しない理由がわかりませんでした。表示したコードは同じ値を生成するはずです。データベースから読み取ったソルトがデータベースに書き込んだソルトと本当に同じかどうかを確認できます。

それにもかかわらず、私はこのルートをさらに進むことを奨励しませんが、ここにはかなり多くの問題があります。

  1. まず第一に、SHA-256はパスワードをハッシュするのに適した選択ではなく、代わりにBCryptのような遅い鍵導出関数を使用します。
  2. 入力データを必要なしにエスケープするべきではありません。エスケープする必要がある場合は、特定のターゲットシステムに対してのみエスケープする必要があります(とにかくハッシュを計算する場合は意味がありません)htmlspecialcharsmysql_real_escape_string
  3. ソルトを作成するには、ランダムソースを使用します。これは良いことです。後でハッシュを使用してソルトを作成しても、ソルトがよりランダムになることはありません。
  4. データベースにパスワードとソルトの2つの別々のフィールドを設定する必要はありません。PHPのcrypt()関数は、すでにソルトを含むハッシュ値を作成します。

パスワードのハッシュに関するこのチュートリアルをお読みください。PHPの例もあります。phpassライブラリを使用することをお勧めします。

于 2012-11-09T08:33:36.727 に答える