2

さて、私は自分のバージョンのSALTを書きました。私はそれをsalty lolと呼んでいます。私をからかってはいけません。とにかく、次のような私のスクリプトの登録部分は100%正しく機能しています。

    //generate SALTY my own version of SALT and I likes me salt.. lol
    function rand_string( $length ) {
        $chars = "ABCDEFGHIJKLMNOPQRSTUWXYZabcdefghijklmnopqrstuwxyz1234567890";
        $size = strlen( $chars );
        for( $i = 0; $i < $length; $i++ ) {
            $str .= $chars[ rand( 0, $size - 1 ) ];
        }
        return $str;
    } 
    $salty = rand_string( 256 );

    //generate my extra salty pw 
    $password = crypt('password');
    $hash = $password . $salty;
    $newpass = $hash;

    //insert the data in the database
    include ('../../scripts/dbconnect.php');

    //Update db record with my salty pw ;)
                                           // TESTED WITH AND WITHOUT SALTY 
                                          //HENCE $password and $newpass
    mysql_query("UPDATE `Register` SET `Password` = '$password' WHERE `emailinput` = '$email'");
    mysql_close($connect);

しかし、私のログインスクリプトは失敗します。ログインするかどうかをテストしてエコーするように設定しました。常にFAILEDを返します。DBに入り、暗号化された塩辛いpwを「TEST」に変更して成功しました。したがって、私の問題は、私が想定しているこのLOGINスクリプトのどこかにあります。$Saltyをこれに実装する方法がわかりません。ただし、SALTYがなくても(暗号を使用してパスを保存するだけで)、ログインを正常に実行できなかったことにも注意してください。そして、あなたが私がblowfishを使うことを提案するつもりなら-私のウェブホストはそれをサポートしておらず、それをインストールする方法がわからないことに注意してください。

これが私のログインスクリプトです:

if (isset($_POST['formsubmitted'])) 
{
include ('../../scripts/dbconnect.php');

$username = mysql_real_escape_string($_POST['username']);
$password = crypt(mysql_real_escape_string($_POST['password']));

$qry = "SELECT ID FROM Register WHERE emailinput='$username' AND Password='$password'"; 
$result = mysql_query($qry);

if(mysql_num_rows($result) > 0) 
{
    echo 'SUCCESS';
    //START SESSION
}
else
{
    echo 'FAILED';
    //YOU ARE NOT LOGGED IN     
}
}
  1. では、このログインの何が問題になっていますか?クリプト/クリプトのみを保存するだけでは機能しないのはなぜですか?

  2. クリプトとランダムに生成されたSALTYの両方を保存して動作させるにはどうすればよいですか:)?

タイアドバンス

4

3 に答える 3

2

このコードを実行するたびに、異なるソルト値が生成されます。したがって、パスワードが最初に保存されるとき、あなたのソルトは(いくつかの例を構成する)になりabcます。パスワードを暗号化します(たとえば123、ソルトを添付すると123abc、データベースに保存されます。

次回ログインしようとすると、新しいランダムソルトが生成されます(たとえば456)。パスワードを暗号化し、ソルトを追加すると、次のようになります123456。そして、あなたの問題があります。これで、2つの完全に異なる文字列が作成されたため、ログインに失敗します。

暗号化されたテキストとは別にソルトを保存する必要があるため、後でソルトを再利用できます。つまり、ログインスクリプトは、最初に、ログインしようとしているユーザーに関連付けられているソルトを取得し、入力したパスワードを再暗号化/ソルトして、文字列が一致するかどうかを確認する必要があります。

また、全体像を見ると、塩漬けを誤って使用していることになります。cryptを介してパスワードを実行するに、パスワードにソルトを追加する必要があります。塩は、パスワードをブルートフォースすることの難しさを増すためにあります。123は単純なパスワードですが、そうで123big_long_ugly_salt_valueはありません。

あなたがしているのは、CPUとストレージのオーバーヘッドを増やすだけで、セキュリティを高めることは何もしない、役に立たない乱数の生成だけです。

于 2012-06-30T02:19:14.070 に答える
1

したがって、保存では、「パスワード」を暗号化してから、$ salty(rand_string)を追加します。

ただし、後でパスワードを比較する場合は、$ _ POST ['password']を暗号化しており、同じランダムな文字列を追加していません。したがって、それらは同じではありません。

パスワード保存手順ごとにランダムにソルトを生成する代わりに、ソルトをどこかに保存するか、ログインが再度行われるときに比較するために後で確実に見つけることができるものからソルトを作成することになります。

これを今すぐ機能させる方法のいくつかのアイデアは、ユーザーIDを使用するか、各ユーザーに異なるソルトを持たせたい場合はソルトとして変更されないその他の情報を使用することです。または、それが問題にならない場合は、独自の他のランダムな文字列を使用して使用できます。

そして、マークBが彼の答えで言ったように、あなたは暗号化する前に塩を追加するべきです。後に追加すると、実際にはパスワードが保護されません。

crypt関数を使用する場合、関数呼び出しにソルトを追加できます。

crypt($ password、$ salt);

そして、あなたがそれを暗号化しているので、私はパスワードのためにmysql_real_escape_stringを実際に台無しにすることはありません。いたずらな文字列の可能性を暗号化しているので、インジェクションについての心配は実際にはありません。

于 2012-06-30T01:58:26.423 に答える
0

私はあなたのコードに次の微調整をします:

function rand_string( $length ) {
    // added period and slash to the alphabet
    $chars = "ABCDEFGHIJKLMNOPQRSTUWXYZabcdefghijklmnopqrstuwxyz1234567890./";
    $size = strlen( $chars );
    for( $i = 0; $i < $length; $i++ ) {
        $str .= $chars[ rand( 0, $size - 1 ) ];
    }
    return $str;
}

// we need 22 random characters
$salty = rand_string(22);
// apply blowfish with cost := 13
$newpass = crypt($password, sprintf('$2y$%02d$%s', 13, $salty));

これはBlowfishを使用してパスワードをハッシュします。強度13で完了するには約0.5秒かかるため、状況によってはそれを減らしたい場合があります。新しいパスワードの場合、コストを変更できます。

ソルトはパスワードと一緒に保存されるので、そのために別の列を用意する必要はありません。

データベースからパスワードを確認するには、最初にそれぞれのRegister行からパスワードフィールドをロードする必要があります。

if (crypt($_POST['password'], $password_from_db) === $password_from_db) {
    // success
} else {
    // password didn't match
}

ところで、比較機能は、タイミング攻撃を防ぐために定数時間アルゴリズムに変換されることがよくあります。


関数salty()は、22文字の長さの塩を生成するために次の同等のものに置き換えることができます。

substr(strtr(base64_encode(openssl_pseudo_random_bytes(18)), '+', '.'), 0, 22);

参照:https ://wiki.php.net/rfc/password_hash

于 2012-06-30T03:10:48.290 に答える