PHPとパスワードのセキュリティ

ここに画像の説明を挿入

暗号化されたパスワード

一般に、パスワードは、ユーザーパスワード(MD5、SHA、その他のアルゴリズムを使用するなど)を保存する前に暗号化してから、データベースに保存する必要があります。

MD5でパスワードを暗号化するコードは次のとおりです。

<?php
	$password = $_POST['password'];
	echo md5($password);
?>

SHA1でパスワードを暗号化するコードは次のとおりです。

<?php
	$password = $_POST['password'];
	echo sha1($password);
?>
有一些攻击者将用户常用的密码总结 出来,再使用这些加密算法得出其加密后的值,
将加密后的值和原始密码保存起来,形成一张可通过密码对原文进行反查的数据表,称其为彩虹表。
攻击者只需要用彩虹表与加密后的密码比对,就能得到用户的原始密码。

パスワードなどの機密情報を暗号化するためにdexやMD5などの弱い暗号化アルゴリズムを使用することはお勧めしません。ハッシュアルゴリズムは、SHA256またはSHA512を使用することをお勧めします。

<?php
	$password = $_POST['password'];
	echo hash("sha256",$password);
?>

PHPにはハッシュ()関数が組み込まれており、暗号化メソッドをハッシュ()関数に渡すだけで、SHA256やSHA512などの暗号化メソッドの使用を直接指定できます。

パスワードとソルト

使用盐(salt)来混淆加密后的值。可以加大攻击者直接从字典密码库中碰撞除用户密码的难度。如果所有
用户的salt一样,且混淆方式已知,那么攻击者依然可以针对常见密码与salt混合生成一张具有针对性的彩虹表

安全率を高めるために、ランダムなソルトを使用する必要があります。ユーザーのパスワードが書き込まれる(パスワードを登録または変更する)たびに、ソルト(ランダムな文字)がランダムに生成され、ソルトとパスワードが混合されます(さまざまな混合方法を使用できます)。 2つを接続するだけではありません)、そしてハッシュ計算。このようにして、攻撃者がレインボーテーブルを持っている場合でも、ユーザーが通常のパスワードを入力しても、salt混合のハッシュ値は元のパスワードと異なるため、どのハッシュ値がどの通常のパスワードに対応するかをすぐに推測することはできません。

ソルトを使用してユーザーパスワードを暗号化するコードは次のとおりです。

<?php
	$password = $_POST['password'];
	$salt = rand(1,10000);
	$password = sha1($password.$salt);
?>

ただし、ソルトがユーザーごとに異なる場合、すべてのユーザーに対してレインボーテーブルを生成することは困難です。しかし、攻撃者は依然としてブルートフォースメソッドを使用して、特定のユーザーに対してパスワードを解読することができます。ユーザーのパスワードの長さが短く、すべての数字に加えて、使用するソルトが単純すぎる場合、およびMD5やSHAなどのアルゴリズムが独自の特性により暗号化プロセスを高速化する場合、簡単に解読される可能性があります。

通常のMD5やその他の高速アルゴリズムの反復回数を増やして複雑なソルトを生成したり、mcryptなどのより複雑な暗号化アルゴリズムを使用して、攻撃者にブルートフォースを強制したり、さらに時間がかかるようにすることができます。暗号化アルゴリズムは微妙に制御されているため、攻撃者の解読に見舞われる可能性があると同時に、シングルユーザーログイン認証の時間が長くなりすぎないため、攻撃者がパスワードを解読する危険を効果的に解決できます。

複数の暗号化のコードは次のとおりです。

<?php

$password = MD5($_POST['password']);
$salt = MD5(rand(1,10000));
$password = sha1($password.$salt);

?>

より長く、より複雑なランダムソルトを生成するコードは次のとおりです。

<?php

$password = $_POST['password''];
$salt = base64_encode(mcrypt_create_iv(32,MCRYPT_DEV_RANDOM);
$password = sha1($password.$salt);

?>

次のようにpassword_hash()関数を使用して、2番目のパラメータをPASSWORD_BCRYPTとして指定し、パスワードコードを暗号化します。

$password = password_hash($password,PASSWORD_BCRYPT);

上記の方法に加えて、独自の方法を使用して文字列を混乱させ、より複雑なパスワード暗号化方法を作成することもできます

<?php

if (defined("CRYPT_BLOWFISH") && (CRYPT_BLOWFISH){
	$salt = '$2y$11$' . substr(md5(uniqid(rand(), true)), 0, 22);
	echo crypt($password, $salt);
}

?>

bcryptは、実際にはふぐとcrypt()関数の組み合わせです。CRYPT_BLOWFISHでふぐが利用可能かどうかを確認し、塩を生成します。しかし、ここで地下室()は塩でなければならないことに留意すべきである$2a$か、$2y$初め

blowfish是区块加密算法中的对称加密的一种
crypt()函数返回使用DES、blowfish或MD5等算法加密的字符串。在不同的操作系统上,该函数的行为不同,某些操作系统支持一种以上的算法类型。

総当たり攻撃を防ぐ

ブルートフォースアトラクト(ブルートフォースアトラクト)は、完全クラックとも呼ばれ、パスワードをクラックする方法です。つまり、実際のパスワードが見つかるまで、パスワードを1つずつ確認しようとします。

一般的な防御方法は次のとおりです

(1)使用验证码进行验证登入
(2)使用Token生成form_hash,然后验证
(3)使用随机数时,要确保用户无法获取随机数生成算法。
(4)身份验证需要用户凭短信、邮件接受验证码时,需要对验证次数进行限制
(5)限制某时间段内验证此数
(6)用户在设置密码时要求用户使用特殊字符和字母数字组合,并限制最小长度

乱数セキュリティ

随机数与密码一样,防止被预测,在各类业务场景中必不可少。随机数有真随机数和伪随机数之分。

真の乱数は、真の乱数ジェネレータ(TRNG)を使用して生成されます。これは、コインを投げる、サイコロ、ランナー、電子部品を使用するノイズ、核分裂などの予測できない物理的方法を使用して生成される乱数です。

疑似乱数は、特定のアルゴリズムまたはシードを使用してコンピューターによって生成される疑似乱数ジェネレーター(PRNG)を使用して生成されます。コンピューター生成の疑似乱数。強力な疑似乱数(予測が難しい乱数)と疑似乱数(予測が容易な乱数)に分かれています。

プロジェクトで乱数が一般的に使用されるシナリオには、パスワードソルト生成、検証コード生成、トークン生成、UUID生成、キー生成、デジタル署名生成、暗号化ベクトル生成、ノンス生成などがあります。

加密向量(IV或SV)是一个固定长度地输入值,使用随机数产生地初始向量才能达到语义安全,并让攻击者难以对同一把密钥地的密文进行破解。在区块加密中,使用了初始向量的加密模式称为区块加密模式
Nonce是Number once的缩写,在密码学中Nonce是一个只被使用一次的任意或非重复的随机数值。

乱数を不適切に使用すると、一連のセキュリティ問題が発生する可能性があります。

(1)在研发过程中使用时间戳作为随机数[MD5(时间戳),MD5(用户ID+时间戳)],但是由于时间戳是可以
	预测的,因此很容易被破解。
(2)生成密码用的slat以及找回密码时的Token,需要一个随机数,如果直接根据用户ID生成Token,很容易
	被攻击者猜解。
(3)OAuth2.0中需要第三方传递一个state参数作为CSRF Token来防止CSRF攻击,很多研发人员根本不适用
	这个参数,或者时传入一个固定的值。由于认证方无法对这个值进行业务层面的有效性校验,导致了OAuth的CSRF攻击。
(4)在抽奖程序中如果使用的随机数不均匀或者可猜解,可直接造成奖品损失。
(5)PHP5在Windows操作系统下调用rand()函数的时候会发生随机数不均匀的情况,其他操作系统不会有这
	样的情况。PHP提供了另一个高质量、非常好的随机数发生器mt_rand(),在涉及项目安全的时候可选用
	这个函数。

デジタルサマリー

デジタルダイジェストはデジタル署名とも呼ばれ、任意の長さのメッセージを固定長の短いメッセージに変換します。これは一方向の不可逆暗号化方式です。一般に、単一ハッシュ関数を使用して、固定長の暗号文の文字列に暗号化する必要がある大きな平文を「暗号化」します。この暗号文の文字列は、デジタル指紋とも呼ばれます。長さ、および暗号文への異なるプレーンテキストダイジェストの結果は常に異なり、同じプレーンテキストダイジェストは一貫している必要があります。デジタル要約は、改ざん防止用の識別のためにインターネット上で送信される情報の暗号化と認証によく使用されます

一般的に使用されるデジタルダイジェストアルゴリズムは、MD5とSHAです。

メッセージダイジェストアルゴリズムMD5(MD5)は、メッセージの整合性保護を提供するためにコンピューターセキュリティの分野で広く使用されているハッシュ関数です。MD5はデジタルサマリーで広く使用されています。元のデータに変更を加えた場合、たとえ1バイトしか変更されていなくても、結果のMD5値は大きく異なるためです。さらに、元のデータとそのMD5値を考えると、同じMD5価値のデータ(つまり、偽造データ)を見つけることは非常に困難です。

MACおよびHMACの概要

メッセージ認証コード(MAC)は、メッセージの送信に基づいてKEYを介して暗号化されたダイジェストを生成します。これは通常、送信中にメッセージが改ざんされたかどうかを検出するために使用されます。MACメッセージ認証プロセスを図に示します。
ここに画像の説明を挿入

メッセージ認証では、メッセージの送信者がキーとMACを介してMACデータタグを計算し、メッセージとMACラベルを受信者に送信します。メッセージの受信者は同じキーを順番に使用して、同じMACアルゴリズムによって生成されたMACタグを比較します。それらが同じである場合、受信者はメッセージが送信中に変更または改ざんされていないと想定できます。

同時に。リプレイ攻撃を防ぐには、メッセージ自体に、タイムスタンプ
、シリアル番号、MACの使用など、1回だけ送信できるようにするデータが含まれている必要があります

ハッシュメッセージ認証コード(HMAC)は、MACアルゴリズムに基づいてハッシュアルゴリズムを暗号化することによって実装されます。

hash_hmac()関数を使用して、MD5メソッドを使用して元のメッセージのハッシュ値を生成します。

<?php
	echo hash_hmac('ma5','LEO学PHP','php_secret_key');
?>

ファイルのハッシュ値を生成する必要がある場合は、hash_hmac_file()関数を使用して、次の例のSHA256アルゴリズムを使用してハッシュ値を生成できます。

<?php
	echo hash_hmac('sha256','/tmp/LEO学PHP.pdf','php_secret_key');
?>

対称暗号化

対称暗号化アルゴリズムとは、データの送信者が平文(元のデータ)と鍵を一緒に暗号化し、それを複雑な暗号化された暗号文に送信することを意味します。受信者が暗号文を受け取った後、元のテキストを解釈したい場合は、暗号化キーと同じアルゴリズムの逆アルゴリズムを使用して、暗号文を解釈し、読み取り可能な平文に復元できるようにする必要があります。対称暗号化アルゴリズムの利点は、アルゴリズムがオープンであり、計算量が少なく、暗号化速度が速く、暗号化効率が高く、大量のデータを暗号化する場合に適しています。一般的に使用されるアルゴリズムは、DES、3DES、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK、AESなどです。

PHPで対称暗号化アルゴリズムを使用する必要がある場合は、mcrypt拡張のサポートが必要です。PHPのmcrypt拡張機能は、強力な暗号化および復号化方法を提供します。関数mcrypt_list_algorithms()およびmcrypt_list + mode()で表示できます。

<pre>
<?php
	$type_list = mcrypt_list_algorithms();	//mcrypt支持的加密算法列表
	$mode_list = mcrypt_list_modes();	//mcrypt支持的加密模式列表
	print_r($type_list);
	print_r($mode_list);
?>
</pre>

ここに画像の説明を挿入

DESで暗号化されたコードは次のとおりです。

<?php 

$auth_key = 'safe_key';
$salt = '!@#$%';
$content = 'Hello World';
$td = mcrypt_module_open(mcrypt_des,'','ecb','');	//使用mcrypt_des算法ecb模式

$iv_size = mcrypt_enc_get_iv_size($td);	//设置初始向量大小
$iv = mcrypt_create_iv($iv_size,mcrypt_rand);	//创建初始向量
$key_size = mcrypt_enc_get_key_size($td);	//返回所支持的最大密钥长度(以字节计算)

$key = substr(md5($auth_key.salt),0,$key_size);
mcrypt_generic_init($td, $key, $iv);	//初始化
$secret = mcrypt_generic($td, $content);	//加密并返回加密后的内容
echo base64_encode($secret);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);	//结束

 ?>

ここに画像の説明を挿入

DESを使用して復号化するコードは次のとおりです。

<?php 

$auth_key = 'safe_key';
$salt = '!@#$%';
$secret = 'Rr6TE6b1+XXiPkJnFUOuMw==';
$td = mcrypt_module_open(mcrypt_des,'','ecb','');	//使用mcrypt_des算法ecb模式

$iv_size = mcrypt_enc_get_iv_size($td);	//设置初始向量大小
$iv = mcrypt_create_iv($iv_size,mcrypt_rand);	//创建初始向量
$key_size = mcrypt_enc_get_key_size($td);	//返回所支持的最大密钥长度(以字节计算)

$key = substr(md5($auth_key.salt),0,$key_size);
mcrypt_generic_init($td, $key, $iv);	//初始化
$content = mdecrypt_generic($td, base64_decode($secret));	//解密并返回内容
echo $content;
mcrypt_generic_deinit($td);
mcrypt_module_close($td);	//结束

 ?>

ここに画像の説明を挿入

AESはAdvanced Enctyption Standard(Advanced Encryption Standard)の略で、暗号化におけるRijindael暗号化方式としても知られており、米国連邦政府によって採用されたブロック暗号化規格です。この標準は、多くの関係者によって分析され、世界中で広く使用されている元のDESを置き換えるために使用されます。
AESには現在5つの暗号化モードがあります。

(1)电码本模式
(2)密码分组链接模式
(3)计数模式
(4)密码反馈模式
(5)输出反馈模式

PHPのmcrypt拡張機能では、rijndael-128、rijndael-192、およびrijndael-256はAES暗号化です。3つのタイプは、暗号化に異なるデータブロックとキー長を使用します。

AES ECBモードでは、通常、16バイトがブロックとして使用され、ブロック全体が暗号化されます。入力文字列が16バイトに足りない場合は、入力する必要があります。

AES CBC暗号化モードでは、初期化ベクトル(IV)を追加する必要があります。zhi6のデフォルト値は16 0です。これはブロック暗号化であるため、次のグループのIVは前のグループの暗号化された暗号文を使用します。CFBモードとOFBモードは似ていますが、より複雑で、解読が困難です。

非対称暗号化

対称暗号化アルゴリズムは、暗号化と復号化に同じキーを使用します。対称暗号化アルゴリズムとは異なり、非対称暗号化アルゴリズムでは、暗号化と復号化に2つのキー(公開キー(公開キー)と秘密キー(秘密キー))が必要です。公開鍵と秘密鍵はペアです。公開鍵を使用してデータを暗号化する場合は、対応する秘密鍵のみを使用して復号化できます。秘密鍵を使用してデータを暗号化する場合は、対応する公開鍵のみ復号化できます。

非対称暗号化で使用される主なアルゴリズムは、RSA、Elgamal、ナップザックアルゴリズム、Rabin、DH、ECC(楕円曲線暗号化アルゴリズム)などです。RSAは、現在最も影響力のある公開鍵暗号化アルゴリズムの1つであり、現在のZhiが知っているパスワード攻撃の大部分。

生成私钥
openssl genrsa -out rsa_private_key.pem 1024
生成公钥
openssl rsa -in rsa_private_key.pem -pubout-out rsa_public_key.pem
<?php 

$private_key_file = "rsa_private_key.pem";
$public_key_file = "rsa_public_key.pem";
$data = "Hello World";
if (file_exists($private_key_file)){
	$private_key_file = file_get_contents($private_key_file);
}
else{
	die('private key not exists');
}

if (file_exists($public_key_file)){
	$public_key = file_get_contents($public_key_file);
}
else{
	die('public key not exists');
}

$encrypted = $decrypted = "";
openssl_private_encrypt($data, $encrypted, $private_key);	//使用私钥加密数据
openssl_public_decrypt($encrypted, $decrypted, $public_key);
//使用公钥界面
echo $decrypted;
$encrypted = $decrypted = "";
openssl_public_encrypt($data, $encrypted, $public_key);//使用公钥进行加密
openssl_private_decrypt($data, $decrypted, $public_key);	//使用私钥进行加密
echo $decrypted;

 ?>

まとめ

さまざまな暗号化方式のアプリケーションシナリオと、パスワードの使用プロセスにおけるセキュリティの問題に焦点を当てています。さまざまなビジネスシナリオに応じて、適切な暗号化方法を選択して、ユーザー情報のセキュリティを確保します。

71件の元の記事を公開 いいね3 訪問4044

おすすめ

転載: blog.csdn.net/zouchengzhi1021/article/details/105341373