2

一部の機能にアクセスするためにユーザー認証が必要な Web サイトを作成しています。現在、ユーザーがアカウントを作成する方法と、セッションを利用してログインを承認する方法に取り組んでいます。ユーザー情報は、user という名前の MySQL テーブルに保存されます。これには、ユーザー名とパスワードの参照が含まれている可能性があります。

セキュリティのためのパスワードハッシュ/ソルトについて読んでいて、私がまだ言語の新人であることを考慮して、何人かのPHPマスターの意見を求めていました。

私は次のスクリプトを書きました:

define('SALT_LENGTH', 6);

function generateHash($plaintext, $salt==null){
    if($salt == null){
        $salt = substr(md5(uniqid(rand(), true)), 0, SALT_LENGTH);
    }
    else{
        $salt = substr($salt, 0, SALT_LENGTH);
    }

    return $salt . sha1($salt . $plaintext);
}
?>

これは、salt を使用してハッシュを生成するために含まれる関数です。

$username = $_POST['username'];
$password = generateHash($_POST['password']);
try{
    $stmt = $pdo->prepare(INSERT INTO user VALUES (:username, :password, :location,     :email, :name);
}catch(PDOException $e){
    echo $e->getMessage();
}
    $stmt->execute(array(':username'=>$username, 
                         ':password'=>$password, 
                         ':location'=>$location, 
                         ':email'=>$email, 
                         ':name'=>$name);

これは、アカウントを作成するためのスクリプトの重要な部分です

if(isset($_POST)){
    //if form was submitted

    $username = $_POST['username'];
    $password = generateHash($_POST['password']);

    session_start();

    $user = 'root';
    $pass = null;
    $pdo = new PDO('mysql:host=localhost; dbname=divebay;', $user, $pass);

    try{
        $stmt = $pdo->prepare('SELECT username FROM user WHERE username =     :username AND password = :password');
        $stmt->execute(array(':username'=>$username,
                             ':password'=>$password);

        if($stmt->fetch(PDO::FETCH_ASSOC)){
            echo 'match';
        }
        else{
            echo 'nomatch';
        }

これは、データベース内のユーザーを検索するためのログイン セッション スクリプトです。

私の主な質問は、このハッシュ/ソルトが機能するように見えるかどうかです。あるインスタンスで暗号化を作成するために使用されるハッシュ (create acct) が、別のインスタンスで作成されたハッシュでどのように機能するかについて混乱しています。さらに、私が作成しようとしているものの複雑さは、適切に展開される可能性が低い比較的単純なソフトウェア プロジェクトに適していますか?

私のスクリプトがどこで間違っているかについての他の提案も高く評価されます (私は批判が必要です)。

4

3 に答える 3

2

あなたへの私のアドバイスは、あなたのためにこれを行うライブラリ/フレームワークを探すことです。多くのフレームワークは、多くの場合、役割ベースの承認を含め、内部でこの種のことを自動的かつ正しく処理します。認証と承認を正しく行うことはそれほど難しいことではありませんが、学習演習として行わない限り、自分で行うことを避けるように努める必要があるほど難しいです。

コードの正確さについては、アカウント名に保存されているパスワードと一致するソルトを使用してパスワードを比較する必要があると思います。データベースで指定されたユーザー名のパスワードハッシュを検索し、そのパスワードハッシュ(正しく追加したもの)からソルトを取得してから、提供されたパスワードで取得したソルトを使用してハッシュを取得する必要があります。次に、ハッシュを保存されているハッシュと文字列比較して認証します。

PHPについてはよくわかりませんが、これを処理するライブラリが存在すると確信しています。

于 2012-07-23T15:31:19.757 に答える
1

塩が提供されていない場合、保存していないランダムなものを取得します。

ユーザーをログに記録しようとするハッシュの後、提供されたパスワードをハッシュし、そのハッシュを計算して、データベースに保存されているものと照合します。ハッシュが時間とともに変化する可能性がある場合、これはハッシュではありません。

生成されたソルトをデータベースに保存するには、一定のソルト (おそらく 6 文字よりも長いソルト) を使用する必要があります。まったく同じ入力に対してまったく同じハッシュを計算できる必要があります。

于 2012-07-23T15:23:36.750 に答える
1

ログイン時のパスワード作成とパスワード チェックの両方で が呼び出される限りgenerateHash、このハッシュは同じ出力 (同じ入力を想定) により適切に機能します。

ただし、現時点では、そうではないようです。$salt(ランダムに生成されるため)をデータベースに保存し、チェック中に取得する必要があります。

于 2012-07-23T15:23:44.190 に答える