国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > PHP > 正文

yii2中關于加密解密的那些事兒

2024-05-04 21:50:24
字體:
來源:轉載
供稿:網友

前言:

Yii提供了方便的幫助函數來讓你用一個安全秘鑰來加密解密數據。數據通過加密函數進行傳輸,這樣只有擁有安全秘鑰的人才能解密。比如,我們需要存儲一些信息到我們的數據庫中,但是,我們需要保證只有擁有安全秘鑰的人才能看到它(即使應用的數據庫泄露)。

大家也都知道,我們做程序的時候,加密解密是繞不開的話題,使用yii2開發應用的時候,都內置了哪些有關加密解密(安全)方便的支持那?本文將為你揭曉。

相關環境:

操作系統及IDE macOS 10.13.1 & PhpStorm2018.1.2

軟件版本 PHP7.1.8 Yii2.0.14

在yii2中,管理加密解密的庫叫做Security,它以yii2組件的形式存在,因此你可以通過Yii::$app->security來獲取并使用它。

Security組件源代碼位置如下

vendor/yiisoft/yii2/base/Security.php

Security組件一共有15個與加密解密(&編碼)相關的公共方法,我們先來列一個清單。

  1. encryptByPassword 
  2. encryptByKey 
  3. decryptByPassword 
  4. decryptByKey 
  5. hkdf 
  6. pbkdf2 
  7. hashData 
  8. validateData 
  9. generateRandomKey 
  10. generateRandomString 
  11. generatePasswordHash 
  12. validatePassword 
  13. compareString 
  14. maskToken 
  15. unmaskToken 

我想有一些你一定沒見過,沒關系,我們一一去了解。

generateRandomString

之所以先說generateRandomString是因為它最常用,起碼我是這樣。

public function generateRandomString($length = 32){...}

生成一個隨機的字符串,參數$length代表這個字符串的長度,默認32位。值得說明的是這個字符串的取值為范圍是[A-Za-z0-9_-]。

generatePasswordHash & validatePassword

generatePasswordHash & validatePassword經常被用來加密用戶密碼以及對密碼是否正確的驗證,自從MD5可能被碰撞后,我們用yii2開發應用的時候,generatePasswordHash函數對密碼進行加密就成為首選了,它調用了crypt函數。

一般用法如下:

  1. // 使用generatePasswordHash為用戶的密碼加密,$hash存儲到庫中 
  2. $hash = Yii::$app->getSecurity()->generatePasswordHash($password); 
  3.  
  4. // 使用validatePassword對密碼進行驗證 
  5. if(Yii::$app->getSecurity()->validatePassword($password$hash)){ 
  6.  // 密碼正確 
  7. }else
  8.  // 密碼錯誤 

generateRandomKey

和generateRandomString類似,生成一個隨機的串,參數為長度,默認為32位,區別在于generateRandomKey生成的不是ASCII。

簡單的說 generateRandomString 約等于 base64_encode(generateRandomKey)。

encryptByPassword & decryptByPassword

編碼和解碼函數,使用一個秘鑰對數據進行編碼,然后通過此秘鑰在對編碼后的數據進行解碼。

例子:

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

要注意,通過上面得到的編碼后的數據不是ASCII,可以通過base64_encode和base64_decode在外層包裝下。

encryptByKey & decryptByKey

同樣是一組編碼和解碼函數,比通過密碼的方式要快。函數聲明為:

  1. public function encryptByKey($data$inputKey$info = null){} 
  2. 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 對已經加了數據前綴的數據進行檢測,如下代碼:

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

如果返回了原始的字符串則表示驗證通過,否則會返回假。

validateData 函數的第三個參數應該與使用  hashData() 生成數據時的值相同. 它指示數據中的散列值是否是二進制格式. 如果為false, 則表示散列值僅由小寫十六進制數字組成. 將生成十六進制數字.

compareString

可防止時序攻擊的字符串比較,用法非常簡單。

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

結果為真則相等,否則不相等。

那么什么是時序攻擊那?我來舉一個簡單的例子。

  1. if($code == Yii::$app->request->get('code')){ 
  2.    

上面的比較邏輯,兩個字符串是從第一位開始逐一進行比較的,發現不同就立即返回 false,那么通過計算返回的速度就知道了大概是哪一位開始不同的,這樣就實現了電影中經常出現的按位破解密碼的場景。

而使用 compareString 比較兩個字符串,無論字符串是否相等,函數的時間消耗是恒定的,這樣可以有效的防止時序攻擊。

maskToken && unmaskToken

maskToken用于掩蓋真實token且不可以壓縮,同一個token最后生成了不同的隨機令牌,在yii2的csrf功能上就使用了maskToken,原理并不復雜,我們看下源碼。

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

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

接下來我們看一個例子代碼:

  1. $token = Yii::$app->security->maskToken("123456"); 
  2. echo Yii::$app->security->unmaskToken($token);// 結果為 123456 

最后我們總結下

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

使用標準算法的密鑰推導: pbkdf2() 和 hkdf();

防止數據篡改: hashData() 和 validateData();

密碼驗證: generatePasswordHash() 和 validatePassword()

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 遂宁市| 常山县| 清水县| 屏山县| 云浮市| 常德市| 兴海县| 定州市| 肥西县| 松阳县| 桃源县| 香格里拉县| 新闻| 讷河市| 宁南县| 屯留县| 沧州市| 沙湾县| 洛南县| 永川市| 湖州市| 富裕县| 临高县| 寿阳县| 玉环县| 中江县| 渭源县| 肇源县| 安阳市| 六枝特区| 西藏| 渑池县| 神农架林区| 台北市| 江川县| 榆中县| 屏南县| 察哈| 新巴尔虎右旗| 中牟县| 扎囊县|