摘要:我們做程序的時候,加密解密是繞不開的話題,使用開發應用的時候,都內置了哪些有關加密解密安全方便的支持那本文將為你揭曉。函數聲明為存在著第三個參數,比如我們可以傳遞會員的等,這樣此信息將和一起作為加密解密的鑰匙。
我們做程序的時候,加密解密是繞不開的話題,使用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個與加密解密(&編碼)相關的公共方法,我們先來列一個清單。
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 & validatePasswordgeneratePasswordHash & 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 && unmaskTokenmaskToken用于掩蓋真實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()
更多Yii原創文章
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/28803.html
摘要:抽象語法樹大致流程生成然后通過類型斷言進行相應的轉換反編譯工具全集小程序推薦逆向反編譯四大工具利器年支持的反編譯工具匯總原文 像軟件加密與解密一樣,javascript的混淆與解混淆同屬于同一個范疇。道高一尺,魔高一丈。沒有永恒的黑,也沒有永恒的白。一切都是資本市場驅動行為,現在都流行你能為人解決什么問題,這個概念。那么市場究竟能容納多少個能解決這種問題的利益者。JS沒有秘密。 其實本...
摘要:函數返回當前請求的基地址,它有一個參數,默認為,代表返回地址不包含主機信息。上面是獲取當前的,我們還可以使用對請求進行修改和刪除等操作。例子更新例子中的參數為是的,很貼心的將將結果返回為。 Url 以前開發項目的時候,我們習慣于把網站網址做一個配置參數保存,善于用yii2的Url各種方法,無形中讓你的代碼更簡單、更靈活、更規范。下面就一一說明一下。 Url::base($scheme ...
摘要:如果像本例中這樣的場景會遇到這樣一個問題,詳見鏈接當請求參數過長或為了安全,就需要用到下載。寫到這里自己都忍不住想錘自己,給自己挖坑不說,這樣來回請求下載,流量,真的是敗家。 這幾天一直在做遠程文件下載的事,現在總算有了解決,特來記錄一下踩過的坑和想揍自己的心 需求 應用場景是這樣的,底層邏輯數據請求接口是由Java寫的,也就是說原始文件存在Java服務端,返回時有加密措施 由于工作...
閱讀 2164·2021-11-11 16:55
閱讀 1684·2019-08-30 15:54
閱讀 2817·2019-08-30 15:53
閱讀 2211·2019-08-30 15:44
閱讀 1152·2019-08-30 15:43
閱讀 964·2019-08-30 11:22
閱讀 1942·2019-08-29 17:20
閱讀 1566·2019-08-29 16:56