ハッシュ化されたパスワードを使用した安全な認証

1つのプロジェクトを開発するときに、タスクはトラフィックを表示し、攻撃者がソースを表示する(パスワードハッシュを見つけることができる)場合に保護を実装するように見えました。 すべてのデータにアクセスできるので、元のパスワードを知らずに誰もサーバーにログインしないでください。 IPアドレスを変更するオプション、入力時に直接パスワードを取得するオプション(キーログ)、または総当たり攻撃は除外されますが、これはWebサイトの関心事ではなくなりました。



パスワードはネットワーク経由で送信されないため、ブラウザーではハッシュが直接使用されます。これには、小さなJavaScriptライブラリSHA-1を使用します 。 MD-1ではなく、SHA-1を使用する理由 SHA-1はもう少し信頼性が高く、JavaScriptライブラリ自体はMD5の同じ(同じサイトにある)よりも小さいと考えられています。



パスワード自体の代わりに、ハッシュhash2 = sha1_hmac(login, password)



が送信されますが、サーバーに保存されるのは彼ではなく、ユーザー名sha1_hmac(hash2, login)



ハッシュです。 これにより、次の例のように、誰かがサーバーからキャッシュされたデータを盗んだ場合、たとえばデータベースからそれを取得したり、ハッシュデータが含まれている場合はphpファイルを読み取ったりした場合、ログインできなくなります。



傍受されたトラフィックから保護するために、ランダムデータ、IPアドレス、およびログインパスワードに基づくリバースハッシュに基づく認証フォームでハッシュが生成されますhash1 = sha1_hmac(password, login); key = sha1(hash1, random_key+remote_addr)



hash1 = sha1_hmac(password, login); key = sha1(hash1, random_key+remote_addr)



。 ランダムに生成されたハッシュキーはセッションに保存されます。



例:

ログインとパスワードに基づいた2つのハッシュをファイルに保存します。1つは逆sha1_hmac(pass, login)



、もう1つは直接ダブルsha1_hmac(sha1_hmac(login, pass), login)



です。

私のログインは変更されません。私のタスクでは必要なため、誰でも好きなように実行できます( type="hidden"



type="text"



置き換えるだけtype="text"



)。

ソースauth.php





<?php



$login = 'test';

//echo hash_hmac( 'sha1', 'pass', $login).'<br>';

$pass1 = '7cc031be8f6cf4073cc4302af78a0c7f555620cb';

//echo hash_hmac( 'sha1', hash_hmac('sha1', $login, 'pass'), $login).'<br>';

$pass2 = '186e9f6871599932a75ba9c4d2be6e858ebbc268';



function key_session($regenerate = false ) {

if (isset($_SESSION[ 'key']) and ! $regenerate) {

$key = $_SESSION[ 'key'];

} else {

$key = hash_hmac( 'sha1', microtime(), mt_rand());

$_SESSION[ 'key'] = $key;

}

return $key;

}



function auth() {

global $login, $pass1, $pass2;

$key = key_session();

$remote_addr = $_SERVER[ 'REMOTE_ADDR'];

$hash = hash_hmac( 'sha1', $key.$remote_addr, $pass1);

if (($_POST[ 'key'] === $hash) and (hash_hmac('sha1', $_POST['password'], $login) === $pass2)) {

//unset($_SESSION[ 'key']);

key_session( true );

$_SESSION[ 'remote_addr'] = $remote_addr;

header( 'Location: auth.php?mode=login');

} else {

$key = key_session( true );

echo <<<EOF

<script type= "text/javascript" src= "sha1.js" ></script>

<script type= "text/javascript" src= "jquery-1.4.2.min.js" ></script>

<form name= "auth" action= "auth.php" method= "post" >

<input type= "hidden" name= "remote_addr" value= "$remote_addr" >

<input type= "hidden" name= "key" value= "$key" >

<input type= "hidden" name= "login" value= "$login" >

$login:

<input type= "password" name= "password" value= "" >

<input type= "submit" >

</form>

<script>

var key = $( 'input[name=key]').val();

var remote_addr = $( 'input[name=remote_addr]').val();

$( 'form[name=auth]').submit(function() {

var login = $( 'input[name=login]').val();

var password = $( 'input[name=password]').val();

var key_hash = hex_hmac_sha1(hex_hmac_sha1(login, password), key+remote_addr);

$( 'input[name=key]').val(key_hash);

var pass_hash = hex_hmac_sha1(password, login);

$( 'input[name=password]').val(pass_hash);

});

$( 'input[name=password]').focus();

</script>

EOF;

}

}



session_start();

if (isset($_SESSION[ 'remote_addr']) and ($_SESSION['remote_addr'] === $_SERVER['REMOTE_ADDR'])) {

if ($_GET[ 'mode'] === 'logout') {

unset($_SESSION[ 'remote_addr']);

auth();

} else {

print_r($_SESSION);

echo '<a href="?mode=logout">Exit</a>';

}

} else {

auth();

}



* This source code was highlighted with Source Code Highlighter .








ソースをダウンロード: auth.zip



例: auth.php-パスワード:パス



PS jQueryが使用されるのは、将来必要になるためです。原則として、上記には必要ありません。



PPSは、JavaScriptのハッシュ関数の引数の順序が、同じPHP関数の場合より逆になっていることに注意します



All Articles