ホームページ バックエンド開発 PHPチュートリアル php ハッシュ関数を理解してパスワードのセキュリティを強化する_PHP チュートリアル

php ハッシュ関数を理解してパスワードのセキュリティを強化する_PHP チュートリアル

Jul 21, 2016 pm 03:31 PM
hash php いいえ 専門家 関数 強化する 複雑な 安全性 パスワード 暗号化 はい 理解する

1. 免責事項
未確認動物学は複雑なテーマであり、私はその専門家ではありません。多くの大学や研究機関がこの分野で長期にわたる研究を行っています。この記事では、Web アプリケーションのパスワードをできるだけシンプルでわかりやすい方法で安全に保存する方法を紹介したいと思います。
2.「ハッシュ」は何をしますか?
「ハッシュは、データの一部 (小さいデータまたは大きいデータ) を文字列や整数などの比較的短いデータに変換します。これは、一方向ハッシュ関数に依存することで実現されます。」いわゆる一方通行とは、元に戻すことが難しい(または実際には不可能)ことを意味します。ハッシュ関数の一般的な例は md5() で、さまざまなコンピューター言語やシステムでよく使われています。

コードをコピーします コードは次のとおりです:
$data = "Hello World";
$hash = md5($data); // b10a8db164e0754105b7a99be72e3fe5


md5( ) 結果は常に 32 文字の文字列ですが、技術的には 128 ビット (16 バイト) の整数として表すこともできます。 md5() を使用して非常に長い文字列やデータを処理できますが、常に取得されるのは固定長のハッシュ値であり、この関数が「一方向」である理由を理解するのにも役立ちます。
3. ハッシュ関数を使用してパスワードを保存します

一般的なユーザー登録プロセス: ユーザーがパスワードフィールドを含む登録フォームに入力します
ユーザーが入力したすべての情報がデータベースに保存されます。 、ハッシュ関数による暗号化処理の前に、パスワードはデータベースに保存されません。
元のパスワードはどこにも保存されなくなるか、破棄されます。
ユーザーログインプロセス:
ユーザーはユーザー名とパスワードを入力します。
プログラムは、登録されているものと同じハッシュ関数を使用してパスワードを暗号化します。
プログラムはデータベースからユーザーを検索し、ハッシュされたパスワードを読み取ります。
プログラムはユーザー名とパスワードを比較します。 , if 一致した場合、ユーザーは承認されています。
パスワードを暗号化する適切な方法を選択する方法については、この記事の後半で説明します。

4. 質問 1: ハッシュ衝突

ハッシュ衝突とは、2 つの異なるコンテンツがハッシュされ、同じハッシュ値が得られることを意味します。ハッシュ衝突の可能性は、使用されるハッシュ アルゴリズムによって異なります。
どうやって作られるの? たとえば、一部の旧式のプログラムは crc32() を使用してパスワードをハッシュします。このアルゴリズムはハッシュ結果として 32 ビット整数を生成します。これは、可能な出力結果が 2^32 (つまり 4,294,967,296) しかないことを意味します。
パスワードをハッシュしましょう:



コードをコピーします
コードは次のとおりです: echo crc32('supersecretpassword') // 出力: 323322056

次に、人が盗んだと仮定します。データベースハッシュ化されたパスワードを取得します。 323322056 を「supersecretpassword」に復元することはできないかもしれませんが、同じ値にハッシュできる別のパスワードを見つけることはできます。これには非常に単純なプログラムのみが必要です:


コードをコピー
コードは次のとおりです: set_time_limit(0); while (true) {
if (crc32(base64_encode($) i)) ) == 323322056) {
echobase64_encode($i);
}
$i++;
}


このプログラムは実行に時間がかかる場合がありますが、最終的には文字列を返します。この文字列を「supersecretpassword」の代わりに使用し、そのパスワードを使用してユーザー アカウントに正常にログインすることができます。
たとえば、上記のプログラムをコンピューターで数か月間実行した後、「MTIxMjY5MTAwNg==」という文字列が得られました。テストしてみましょう:


コードをコピーします

コードは次のとおりです:
echo crc32('supersecretpassword'); // 出力: 323322056 echo crc32('MTIxMjY5MTAwNg=='); //出力: 323322056

どうやって解決しますか?
現在、もう少し強力な家庭用 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

結果のハッシュ値には、$2a アルゴリズム、コスト パラメーター $10、および使用した 22 ビット干渉文字列が含まれています。残りは計算されたハッシュ値です。テスト プログラムを実行してみましょう:

コードをコピーします コードは次のとおりです:
// これがデータベースから取得されたものと仮定します
$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

tru​​e

技術記事 1. セキュリティコード学は複雑な問題であり、私たちもこの分野の専門家ではありません。多くの高校と研究機関がこの点で長期にわたる研究を行っています。
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

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

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Dec 24, 2024 pm 04:42 PM

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

今まで知らなかったことを後悔している 7 つの PHP 関数 今まで知らなかったことを後悔している 7 つの PHP 関数 Nov 13, 2024 am 09:42 AM

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

PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 Dec 20, 2024 am 11:31 AM

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

JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 Apr 05, 2025 am 12:04 AM

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

PHPでHTML/XMLを解析および処理するにはどうすればよいですか? PHPでHTML/XMLを解析および処理するにはどうすればよいですか? Feb 07, 2025 am 11:57 AM

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

母音を文字列にカウントするPHPプログラム 母音を文字列にカウントするPHPプログラム Feb 07, 2025 pm 12:12 PM

文字列は、文字、数字、シンボルを含む一連の文字です。このチュートリアルでは、さまざまな方法を使用して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での後期静的結合を説明します(静的::)。 PHPでの後期静的結合を説明します(静的::)。 Apr 03, 2025 am 12:04 AM

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

PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? Apr 03, 2025 am 12:03 AM

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

See all articles