ホームページ  >  記事  >  バックエンド開発  >  yii2 の暗号化と復号化の問題について

yii2 の暗号化と復号化の問題について

不言
不言オリジナル
2018-06-12 16:51:132210ブラウズ

この記事は、主に yii2 の暗号化と復号化に関する問題を紹介しています。これは、必要な友人全員に参照してもらうために共有します。

##Yii は、セキュリティ キーを使用してデータを暗号化および復号化できる便利なヘルパー関数を提供します。データは暗号化機能を介して送信されるため、セキュリティ キーを持っている人だけがデータを復号化できます。たとえば、データベースに何らかの情報を保存する必要がありますが、(アプリケーションのデータベースが漏洩した場合でも) セキュリティ キーを持つ人だけがその情報を見ることができるようにする必要があります。 誰もが知っているように、プログラムを作成する場合、暗号化と復号化は避けられないトピックです。yii2 を使用してアプリケーションを開発する場合、暗号化と復号化 (セキュリティ) に関するどのような便利なサポートが組み込まれていますか?この記事ではそれを明らかにします。

#関連環境


## オペレーティング システムと IDE macOS 10.13.1 & PhpStorm2018.1.2

ソフトウェアバージョン PHP7.1.8 Yii2.0.14
  • yii2 では、暗号化と復号化を管理するライブラリは Security と呼ばれ、yii2 コンポーネントとして存在します。 Yii::$app->security を通じて取得して使用できます。
  • #セキュリティ コンポーネントのソース コードの場所は次のとおりです。

vendor/yiisoft/yii2/base/Security.php

セキュリティ コンポーネントには、暗号化と復号化 (&エンコーディング) に関連するパブリック メソッドが合計 15 個あります。まずリストを作成しましょう。

##encryptByPassword


encryptByKey

    ##decryptByPassword
  • decryptByKey
  • hkdf
  • pbkdf2
  • hashData
  • validateData
  • generateRandomKey
  • generateRandomString
  • generatePasswordHash
  • validatePassword

  • ##compareString
  • ##maskToken
  • unmaskToken
  • 見たことのないものもあると思いますが、それは問題ありませんので、一つずつ学んでいきましょう。
  • generateRandomString
  • generateRandomString について最初に説明する理由は、少なくとも私にとってはこれが最も一般的に使用されているためです。
  • public function generateRandomString($length = 32){...}

ランダムな文字列を生成します。パラメータ $length は文字列の長さを表します。デフォルトは 32 ビットです。この文字列の値の範囲は [A-Za-z0-9_-] であることを説明する価値があります。

generatePasswordHash & validatePassword

##generatePasswordHash & validatePassword は、MD5 以降、ユーザーのパスワードを暗号化し、パスワードが正しいかどうかを確認するためによく使用されます。衝突する可能性があるため、yii2 を使用してアプリケーションを開発する場合、generatePasswordHash 関数がパスワードを暗号化するための最初の選択肢となり、crypt 関数を呼び出します。

一般的な使用法は次のとおりです

// 使用generatePasswordHash为用户的密码加密,$hash存储到库中
$hash = Yii::$app->getSecurity()->generatePasswordHash($password);

// 使用validatePassword对密码进行验证
if(Yii::$app->getSecurity()->validatePassword($password, $hash)){
 // 密码正确
}else{
 // 密码错误
}

##generateRandomKey
#generateRandomString と同様に、パラメータは長さであり、デフォルトは 32 ビットです。違いは、generateRandomKey が ASCII を生成しないことです。

簡単に言えば、generateRandomString は、base64_encode(generateRandomKey) とほぼ同じです。

encryptByPassword と decryptByPassword

エンコード関数とデコード関数は、秘密キーを使用してデータをエンコードし、この秘密キーを使用してデータをエンコードします。 エンコードされたデータをデコードします。

$dat = Yii::$app->security->encryptByPassword("hello","3166886");
echo Yii::$app->security->encryptByPassword($dat,"3166886");// hello

注意すべき点は、 で得られた符号化データは次のとおりです。 ASCII ではなく、base64_encode およびbase64_decode を介して外側のラッパーで使用できます。

encryptByKey & decryptByKey

もエンコード関数とデコード関数のセットであり、パスワードを渡すよりも高速です。この関数は

public function encryptByKey($data, $inputKey, $info = null){}

public function decryptByKey($data, $inputKey, $info = null){}

encryptByKey & decryptByKey として宣言されます。たとえば、メンバーの ID などを渡すことができます。情報は $inputKey とともに暗号化および復号化に使用されます。

hkdf
標準の HKDF アルゴリズムを使用して、指定された入力キーからキーを導出します。 PHP7 では hash_hkdf メソッドが使用され、PHP7 では hash_hmac メソッドが使用されます。

pbkdf2

標準の PBKDF2 アルゴリズムを使用して、指定されたパスワードからキーを導出します。この方法はパスワード暗号化に使用できますが、yii2 にはより優れたパスワード暗号化ソリューションのgeneratePasswordHashがあります。

hashData と validateData

#コンテンツの改ざんを防ぐために、データにマークを付ける必要がある場合があります。 hashData と validateData このタスクを完了するのはこの組み合わせです。

hashData は、次のコードのように、元のデータにデータ プレフィックスを追加するために使用されます。

$result = Yii::$app->security->hashData("hello",'123456',false);
// ac28d602c767424d0c809edebf73828bed5ce99ce1556f4df8e223faeec60eddhello

你看到了在hello的前面多了一组字符,这组字符会随着原始数据的不同而变化。这样我们就对数据进行了特殊的防止篡改标记,接下来是validateData上场了。

注意:hashData的第三个参数代表生成的哈希值是否为原始二进制格式. 如果为false, 则会生成小写十六进制数字.

validateData 对已经加了数据前缀的数据进行检测,如下代码

$result = Yii::$app->security->validateData("ac28d602c767424d0c809edebf73828bed5ce99ce1556f4df8e223faeec60eddhello",'123456',false);
// hello

如果返回了原始的字符串则表示验证通过,否则会返回假。

validateData 函数的第三个参数应该与使用  hashData() 生成数据时的值相同. 它指示数据中的散列值是否是二进制格式. 如果为false, 则表示散列值仅由小写十六进制数字组成. 将生成十六进制数字.

compareString

可防止时序攻击的字符串比较,用法非常简单。

Yii::$app->security->compareString("abc",'abc');

结果为真则相等,否则不相等。

那么什么是时序攻击那?我来举一个简单的例子。

if($code == Yii::$app->request->get('code')){
 
}

上面的比较逻辑,两个字符串是从第一位开始逐一进行比较的,发现不同就立即返回 false,那么通过计算返回的速度就知道了大概是哪一位开始不同的,这样就实现了电影中经常出现的按位破解密码的场景。

而使用 compareString 比较两个字符串,无论字符串是否相等,函数的时间消耗是恒定的,这样可以有效的防止时序攻击。

maskToken && unmaskToken

maskToken用于掩盖真实token且不可以压缩,同一个token最后生成了不同的随机令牌,在yii2的csrf功能上就使用了maskToken,原理并不复杂,我们看下源码。

public function maskToken($token){
 $mask = $this->generateRandomKey(StringHelper::byteLength($token));
 return StringHelper::base64UrlEncode($mask . ($mask ^ $token));
}

而unmaskToken目的也很明确,用于得到被maskToken掩盖的token。

接下来我们看一个例子代码

$token = Yii::$app->security->maskToken("123456");
echo Yii::$app->security->unmaskToken($token);// 结果为 123456

最后我们总结下

  • 加密/解密: encryptByKey()、decryptByKey()、 encryptByPassword() 和 decryptByPassword();

  • 使用标准算法的密钥推导: pbkdf2() 和 hkdf();

  • 防止数据篡改: hashData() 和 validateData();

  • 密码验证: generatePasswordHash() 和 validatePassword()

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

以上がyii2 の暗号化と復号化の問題についての詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。