首頁 >後端開發 >php教程 >關於yii2中加密解密的問題

關於yii2中加密解密的問題

不言
不言原創
2018-06-12 16:51:132290瀏覽

這篇文章主要介紹了關於yii2中加密解密的問題,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

前言

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個與加密解密(&編碼)相關的公共方法,我們先來列一個清單。

  • encryptByPassword

  • #encryptByKey

  • ##decryptByPassword

  • decryptByPassword
  • decryptByPassword

  • decryptByPassword
  • 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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn