php ハッシュ関数を理解してパスワードのセキュリティを強化する_PHP チュートリアル
1. 免責事項
未確認動物学は複雑なテーマであり、私はその専門家ではありません。多くの大学や研究機関がこの分野で長期にわたる研究を行っています。この記事では、Web アプリケーションのパスワードをできるだけシンプルでわかりやすい方法で安全に保存する方法を紹介したいと思います。
2.「ハッシュ」は何をしますか?
「ハッシュは、データの一部 (小さいデータまたは大きいデータ) を文字列や整数などの比較的短いデータに変換します。これは、一方向ハッシュ関数に依存することで実現されます。」いわゆる一方通行とは、元に戻すことが難しい(または実際には不可能)ことを意味します。ハッシュ関数の一般的な例は md5() で、さまざまなコンピューター言語やシステムでよく使われています。
md5( ) 結果は常に 32 文字の文字列ですが、技術的には 128 ビット (16 バイト) の整数として表すこともできます。 md5() を使用して非常に長い文字列やデータを処理できますが、常に取得されるのは固定長のハッシュ値であり、この関数が「一方向」である理由を理解するのにも役立ちます。
一般的なユーザー登録プロセス: ユーザーがパスワードフィールドを含む登録フォームに入力します
ユーザーが入力したすべての情報がデータベースに保存されます。 、ハッシュ関数による暗号化処理の前に、パスワードはデータベースに保存されません。元のパスワードはどこにも保存されなくなるか、破棄されます。
ユーザーログインプロセス:
ユーザーはユーザー名とパスワードを入力します。
プログラムは、登録されているものと同じハッシュ関数を使用してパスワードを暗号化します。
プログラムはデータベースからユーザーを検索し、ハッシュされたパスワードを読み取ります。
プログラムはユーザー名とパスワードを比較します。 , if 一致した場合、ユーザーは承認されています。
パスワードを暗号化する適切な方法を選択する方法については、この記事の後半で説明します。
4. 質問 1: ハッシュ衝突
ハッシュ衝突とは、2 つの異なるコンテンツがハッシュされ、同じハッシュ値が得られることを意味します。ハッシュ衝突の可能性は、使用されるハッシュ アルゴリズムによって異なります。
どうやって作られるの? たとえば、一部の旧式のプログラムは crc32() を使用してパスワードをハッシュします。このアルゴリズムはハッシュ結果として 32 ビット整数を生成します。これは、可能な出力結果が 2^32 (つまり 4,294,967,296) しかないことを意味します。
パスワードをハッシュしましょう:
コードをコピーします
次に、人が盗んだと仮定します。データベースハッシュ化されたパスワードを取得します。 323322056 を「supersecretpassword」に復元することはできないかもしれませんが、同じ値にハッシュできる別のパスワードを見つけることはできます。これには非常に単純なプログラムのみが必要です:
コードをコピー
}
$i++;
}
このプログラムは実行に時間がかかる場合がありますが、最終的には文字列を返します。この文字列を「supersecretpassword」の代わりに使用し、そのパスワードを使用してユーザー アカウントに正常にログインすることができます。
たとえば、上記のプログラムをコンピューターで数か月間実行した後、「MTIxMjY5MTAwNg==」という文字列が得られました。テストしてみましょう:
コードは次のとおりです:
どうやって解決しますか?
現在、もう少し強力な家庭用 PC はハッシュ関数を 1 秒あたり 10 億回実行できるため、より広範囲の結果を生成できるハッシュ関数が必要です。たとえば、md5() は 128 ビットのハッシュ値を生成できるため、340,282,366,920,938,463,463,374,607,431,768,211,456 個の出力が可能になります。したがって、ハッシュの衝突を見つけるためにこれほど多くのループを実行することは一般に不可能です。ただし、まだこれを行う方法を見つけている人もいます。詳細については例を参照してください。
sha1() は最大 160 ビットのハッシュ値を生成するため、より良い代替手段です。
5. 問題 2: レインボーテーブル
衝突の問題が解決されたとしても、まだ十分に安全ではありません。
「レインボー テーブルは、一般的に使用される単語とその組み合わせのハッシュ値を計算して構築されたテーブルです。」
このテーブルには数百万、さらには数十億のデータが格納される可能性があります。ストレージが非常に安価になったので、非常に大きなレインボー テーブルを構築できるようになりました。
ここで、ある人がデータベースを盗み、何百万ものハッシュ化されたパスワードを取得したとします。泥棒はレインボー テーブルでこれらのハッシュを 1 つずつ簡単に検索し、元のパスワードを取得できます。すべてのハッシュ値がレインボー テーブルで見つかるわけではありませんが、いくつかは確実に見つかります。
どうやって解決しますか?
次の例のように、パスワードに何らかの干渉を追加してみることができます。
$password = "easypassword"
// これは次のとおりです。レインボーテーブルで見つかりました
// パスワードには一般的な単語が 2 つ含まれているため
echo sha1($password); // 6c94d3b42518febd4ad747801d50a8972022f956
// ランダムな文字を使用し、これよりも長くなる可能性があります
$salt = "f#@V )Hu^%Hgfds";
// これは、事前に構築されたレインボー テーブルには見つかりません
echo sha1($salt . $password); // cd56a16759623378628c0d9336af69b74d9d71a5
ここで行うのは、それぞれの前に干渉文字列を追加することだけですパスワード ハッシュの場合、添付された文字列が十分に複雑である限り、ハッシュされた値は事前に構築されたレインボー テーブルには絶対に見つかりません。しかし、今でも十分に安全とは言えません。
6. 質問 3: まだ虹のテーブルです
虹のテーブルは文字列を盗んだ後に最初から作成される可能性があることに注意してください。干渉文字列もデータベースと一緒に盗まれる可能性があり、その後、この干渉文字列を使用してレインボー テーブルを最初から作成することができます。たとえば、「easypassword」のハッシュ値は通常のレインボー テーブルに存在する可能性がありますが、新しいレインボー テーブルには存在します。レインボーテーブルには「f#@V)Hu^%Hgfdseasypassword」のハッシュ値も存在します。
どうやって解決しますか?
各ユーザーに固有の気を散らす文字列を使用できます。利用可能な解決策の 1 つは、データベース内のユーザー ID を使用することです:
$hash = sha1($user_id . $password);
この前提この方法は、ユーザー ID が定数値であるということです (これは一般的なアプリケーションの場合です)
ユーザーごとに一意の干渉文字列をランダムに生成することもできますが、この文字列を保存する必要もあります:
// 22 文字の長さのランダムな文字列を生成します
function unique_salt() {
return substr(sha1(mt_rand()),0,22)
}
$unique_salt = unique_salt( );
$ hash = sha1($unique_salt . $password);
// そして $unique_salt をユーザー レコードとともに保存します
// ...
この方法は、各パスワードが異なる文字列に干渉されるため、レインボー テーブルによる被害を防ぎます。攻撃者はパスワードと同じ数のレインボー テーブルを作成する必要がありますが、これは現実的ではありません。
7. 質問 4: ハッシュ速度
ほとんどのハッシュ アルゴリズムは、一般に大規模なデータまたはファイルのハッシュ値を計算してデータの正確性と整合性を検証するために使用されるため、速度を念頭に置いて設計されています。
どうやって作られるの?
前に述べたように、強力な PC は 1 秒あたり数十億回の計算を実行できるため、ブルート フォースを使用してあらゆるパスワードを試すことが簡単になります。 8 文字を超えるパスワードを使用すればブルート フォース クラッキングを回避できると思うかもしれませんが、本当にそうなのかを見てみましょう:
パスワードに小文字、大文字、数字を含めることができる場合、62 (26+26+10) になります。 ) 文字はオプションです。
8 桁のパスワードには 62^8 通りの組み合わせがあり、これは 218 兆をわずかに超えます。
1 秒あたり 10 億のハッシュ値を計算する速度に基づくと、解決にかかる時間はわずか 60 時間です。
これも非常に一般的なパスワードである 6 桁のパスワードの場合、解読にはわずか 1 分しかかかりません。 9 ~ 10 桁のパスワードを要求する方が安全かもしれませんが、ユーザーによっては面倒に感じる場合もあります。
どうやって解決しますか?
より遅いハッシュ関数を使用してください。
「同じハードウェア条件下で、1 秒あたり 10 億回実行できるアルゴリズムの代わりに、1 秒あたり 100 万回しか実行できないアルゴリズムを使用すると、攻撃者はブルート フォース クラッキングに 1,000 倍の時間を費やす必要がある可能性があります。」 、60時間 たったの7年になります!」
このメソッドは自分で実装できます:
function myhash($password, $unique_salt) {
$salt = "f#@V )Hu^%Hgfds";
$hash = sha1($unique_salt . $password);
// 1000 倍の時間がかかります
for ($i = 0; $i $hash = sha1($hash);
}
return $hash;
}
BLOWFISH などの「コスト パラメーター」をサポートするアルゴリズムを使用することもできます。 crypt() 関数を使用して php で実装できます:
function myhash($password, $unique_salt) {
// フグの塩は 22 である必要があります文字数
return crypt ($password, '$2a$10.$unique_salt');
}
この関数の 2 番目のパラメーターには、「$」記号で区切られた複数の値が含まれます。最初の値は「$2a」で、BLOWFISH アルゴリズムを使用する必要があることを示します。 2 番目のパラメーター「$10」はここではコスト パラメーターであり、底 2 の対数で、計算ループの反復数 (10 => 2^10 = 1024) を示し、値は 04 ~ 31 です。
例:
function myhash($password, $unique_salt) {
return crypt($password, '$2a$10.$unique_salt');
}
function unique_salt() {
return substr(sha1(mt_rand()),0,22);
}
$password = "verysecret";
// 結果: $2a$10 $dfda807d832b094184faeu1elwhtR2Xhtuvs3R9J1nfRGBCudCCzC
$hash = '$2a$10$ dfda807d832b094184faeu1elwhtR2Xhtuvs3R9J 1nfRGBCudCCzC ';
// これがユーザーが再度ログインするために入力したパスワードであると仮定します
$password = "verysecret";
if (check_password($hash, $password)) {
echo "アクセスが許可されました!";
} else {
echo "アクセスが拒否されました!";
}
function check_password($hash, $password) {
// 最初の 29 文字にはアルゴリズム、コスト、ソルトが含まれます
// $full_salt と呼びましょう
$full_salt = substr($ hash, 0, 29);
// $password でハッシュ関数を実行します
$new_hash = crypt($password, $full_salt);
// true または false を返します
return ($hash == $new_hash);
実行すると、「Access Granted!」が表示されます
8. 統合します
上記の議論に基づいて、ツール クラスを作成しました:
class PassHash {
// フグ
private static $algo = '$2a';
// コストパラメータ
private static $cost = '$10';
// 主に内部使用用
public static function unique_salt() {
return substr(sha1(mt_rand()),0,22);
}
// これはハッシュの生成に使用されます
public static function hash($password) {
return crypt($password,
self::$algo .
self::$cost .
'$'.self ::unique_salt());
}
// これはパスワードとハッシュを比較するために使用されます
public static function check_password($hash, $password) {
$full_salt = substr($hash, 0, 29);
$new_hash = crypt($password, $full_salt);
return ($hash == $new_hash);
}
}
以下は注册時の使用法:
// クラス
require ("PassHash.php") をインクルードします。
// $_POST からすべてのフォーム入力を読み取ります
// ...
// 通常のフォーム検証作業を実行します
// ...
// パスワードをハッシュします
$pass_hash = PassHash::hash($_POST['パスワード']);
// $_POST['password'] を除くすべてのユーザー情報を DB に保存します
// 代わりに $pass_hash を保存します
// ...
以下は登录時の使用法:
// クラス
require ("PassHash.php"); をインクルードします。
// $_POST からすべてのフォーム入力を読み取ります
// ...
// $_POST['username'] または同様のものに基づいてユーザー レコードを取得します
// ...
// ユーザーが試行したパスワードを確認します
if (PassHash::check_password($user['pass_hash'], $_POST['password']) {
// アクセスを許可
// ...
} else {
// アクセスを拒否
// でログインします...
}
9.加密がサポートされているかどうか
并不是全システム统都サポートBlowfish加密算法,虽然它现在已经很普及了,你可以以下代码来检查你的システム统がサポートされているかどうか:
if (CRYPT_BLOWFISH == 1) {
echo "Yes";
} else {
echo "No";
php5.3 では不过对背負う心この方法が組み込まれているため、この方法で暗号化された暗号は、ほとんどの Web アプリケーション プログラムに対して十分に安全であると考えられます。用人使用安全度最小ビット数が必要な場合など、より高度な暗号には、文字、数字、特殊文字の混合暗号などが使用されます。
http://www.bkjia.com/PHPjc/322921.html
www.bkjia.com
true

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

あなたが経験豊富な PHP 開発者であれば、すでにそこにいて、すでにそれを行っていると感じているかもしれません。あなたは、運用を達成するために、かなりの数のアプリケーションを開発し、数百万行のコードをデバッグし、大量のスクリプトを微調整してきました。

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

このチュートリアルでは、PHPを使用してXMLドキュメントを効率的に処理する方法を示しています。 XML(拡張可能なマークアップ言語)は、人間の読みやすさとマシン解析の両方に合わせて設計された多用途のテキストベースのマークアップ言語です。一般的にデータストレージに使用されます

文字列は、文字、数字、シンボルを含む一連の文字です。このチュートリアルでは、さまざまな方法を使用してPHPの特定の文字列内の母音の数を計算する方法を学びます。英語の母音は、a、e、i、o、u、そしてそれらは大文字または小文字である可能性があります。 母音とは何ですか? 母音は、特定の発音を表すアルファベットのある文字です。大文字と小文字など、英語には5つの母音があります。 a、e、i、o、u 例1 入力:string = "tutorialspoint" 出力:6 説明する 文字列「TutorialSpoint」の母音は、u、o、i、a、o、iです。合計で6元があります

静的結合(静的::) PHPで後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。

PHPの魔法の方法は何ですか? PHPの魔法の方法には次のものが含まれます。1。\ _ \ _コンストラクト、オブジェクトの初期化に使用されます。 2。\ _ \ _リソースのクリーンアップに使用される破壊。 3。\ _ \ _呼び出し、存在しないメソッド呼び出しを処理します。 4。\ _ \ _ get、dynamic属性アクセスを実装します。 5。\ _ \ _セット、動的属性設定を実装します。これらの方法は、特定の状況で自動的に呼び出され、コードの柔軟性と効率を向上させます。
