主頁 > 知識(shí)庫(kù) > yii2中關(guān)于加密解密的那些事兒

yii2中關(guān)于加密解密的那些事兒

熱門標(biāo)簽:拉薩打電話機(jī)器人 高識(shí)別電銷機(jī)器人 h5 地圖標(biāo)注 合肥外呼系統(tǒng)app 寶安400電話辦理 哈爾濱400電話辦理到易號(hào)網(wǎng) 沈陽人工智能電銷機(jī)器人公司 智能外呼電銷系統(tǒng) 電銷機(jī)器人-快迭智能

前言

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

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

相關(guān)環(huán)境

  • 操作系統(tǒng)及IDE macOS 10.13.1 PhpStorm2018.1.2
  • 軟件版本 PHP7.1.8 Yii2.0.14

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

Security組件源代碼位置如下

vendor/yiisoft/yii2/base/Security.php

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

  • encryptByPassword
  • encryptByKey
  • decryptByPassword
  • decryptByKey
  • hkdf
  • pbkdf2
  • hashData
  • validateData
  • generateRandomKey
  • generateRandomString
  • generatePasswordHash
  • validatePassword
  • compareString
  • maskToken
  • unmaskToken

我想有一些你一定沒見過,沒關(guān)系,我們一一去了解。

generateRandomString

之所以先說generateRandomString是因?yàn)樗畛S?,起碼我是這樣。

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

生成一個(gè)隨機(jī)的字符串,參數(shù)$length代表這個(gè)字符串的長(zhǎng)度,默認(rèn)32位。值得說明的是這個(gè)字符串的取值為范圍是[A-Za-z0-9_-]。

generatePasswordHash validatePassword

generatePasswordHash validatePassword經(jīng)常被用來加密用戶密碼以及對(duì)密碼是否正確的驗(yàn)證,自從MD5可能被碰撞后,我們用yii2開發(fā)應(yīng)用的時(shí)候,generatePasswordHash函數(shù)對(duì)密碼進(jìn)行加密就成為首選了,它調(diào)用了crypt函數(shù)。

一般用法如下

// 使用generatePasswordHash為用戶的密碼加密,$hash存儲(chǔ)到庫(kù)中
$hash = Yii::$app->getSecurity()->generatePasswordHash($password);

// 使用validatePassword對(duì)密碼進(jìn)行驗(yàn)證
if(Yii::$app->getSecurity()->validatePassword($password, $hash)){
 // 密碼正確
}else{
 // 密碼錯(cuò)誤
}

generateRandomKey

和generateRandomString類似,生成一個(gè)隨機(jī)的串,參數(shù)為長(zhǎng)度,默認(rèn)為32位,區(qū)別在于generateRandomKey生成的不是ASCII。

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

encryptByPassword decryptByPassword

編碼和解碼函數(shù),使用一個(gè)秘鑰對(duì)數(shù)據(jù)進(jìn)行編碼,然后通過此秘鑰在對(duì)編碼后的數(shù)據(jù)進(jìn)行解碼。

例子

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

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

encryptByKey decryptByKey

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

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

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

encryptByKey decryptByKey 存在著第三個(gè)參數(shù),比如我們可以傳遞會(huì)員的ID等,這樣此信息將和$inputKey一起作為加密解密的鑰匙。

hkdf

使用標(biāo)準(zhǔn)的 HKDF 算法從給定的輸入鍵中導(dǎo)出一個(gè)鍵。在PHP7+使用的是hash_hkdf方法,小于PHP7使用hash_hmac方法。

pbkdf2

使用標(biāo)準(zhǔn)的 PBKDF2 算法從給定的密碼導(dǎo)出一個(gè)密鑰。該方法可以用來進(jìn)行密碼加密,不過yii2有更好的密碼加密方案 generatePasswordHash。

hashData和validateData

有的時(shí)候?yàn)榱朔乐箖?nèi)容被篡改,我們需要對(duì)數(shù)據(jù)進(jìn)行一些標(biāo)記,hashData和validateData就是完成這個(gè)任務(wù)的組合。

hashData 用來對(duì)原始數(shù)據(jù)進(jìn)行加數(shù)據(jù)前綴,比如如下代碼

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

你看到了在hello的前面多了一組字符,這組字符會(huì)隨著原始數(shù)據(jù)的不同而變化。這樣我們就對(duì)數(shù)據(jù)進(jìn)行了特殊的防止篡改標(biāo)記,接下來是validateData上場(chǎng)了。

注意:hashData的第三個(gè)參數(shù)代表生成的哈希值是否為原始二進(jìn)制格式. 如果為false, 則會(huì)生成小寫十六進(jìn)制數(shù)字.

validateData 對(duì)已經(jīng)加了數(shù)據(jù)前綴的數(shù)據(jù)進(jìn)行檢測(cè),如下代碼

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

如果返回了原始的字符串則表示驗(yàn)證通過,否則會(huì)返回假。

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

compareString

可防止時(shí)序攻擊的字符串比較,用法非常簡(jiǎn)單。

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

結(jié)果為真則相等,否則不相等。

那么什么是時(shí)序攻擊那?我來舉一個(gè)簡(jiǎn)單的例子。

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

上面的比較邏輯,兩個(gè)字符串是從第一位開始逐一進(jìn)行比較的,發(fā)現(xiàn)不同就立即返回 false,那么通過計(jì)算返回的速度就知道了大概是哪一位開始不同的,這樣就實(shí)現(xiàn)了電影中經(jīng)常出現(xiàn)的按位破解密碼的場(chǎng)景。

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

maskToken unmaskToken

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

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

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

接下來我們看一個(gè)例子代碼

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

最后我們總結(jié)下

  • 加密/解密: encryptByKey()、decryptByKey()、 encryptByPassword() 和 decryptByPassword();
  • 使用標(biāo)準(zhǔn)算法的密鑰推導(dǎo): pbkdf2() 和 hkdf();
  • 防止數(shù)據(jù)篡改: hashData() 和 validateData();
  • 密碼驗(yàn)證: generatePasswordHash() 和 validatePassword()

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

您可能感興趣的文章:
  • Yii2框架可逆加密簡(jiǎn)單實(shí)現(xiàn)方法

標(biāo)簽:泰州 山東 林芝 張家口 梅州 威海 成都 巴中

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《yii2中關(guān)于加密解密的那些事兒》,本文關(guān)鍵詞  yii2,中,關(guān)于,加密解密,的,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《yii2中關(guān)于加密解密的那些事兒》相關(guān)的同類信息!
  • 本頁收集關(guān)于yii2中關(guān)于加密解密的那些事兒的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章