這篇文章主要介紹了關於yii2加密和解密的介紹,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下
相關環境
在yii2中,管理加密解密的庫叫做Security,它以yii2組件的形式存在,因此你可以通過Yii::$app->security來擷取並使用它。
Security組件原始碼位置如下
vendor/yiisoft/yii2/base/Security.php
Security組件一共有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()
以上就是本文的全部內容,希望對大家的學習有所協助,更多相關內容請關注topic.alibabacloud.com!