天天看點

Yii 2 —— 密碼加密算法

參考文檔:

Yii 2預設用user表儲存賬号資訊,包括使用者的密碼,user表結構如下:

id

username

賬号

auth_key

password_hash

儲存密碼的hash值

password_reset_token

忘記密碼,重置密碼用的token

email

status

created_at

updated_at

PHP 5.5以後,提供了新的密碼加密函數password_hash(),這個加密函數有三個參數,第一個參數就是待加密的密碼,第二個參數是加密算法,推薦使用PASSWORD_DEFAULT,這樣可以随着PHP的更新,自動選用新的更新算法,第三個參數是加密算法執行次數,一般來說次數越多,密碼強度越大,但是花費的時間越多。

使用password_hash()加密時,每調用一次就會使用新的solt,是以即使是同樣的密碼,每次調用password_hash()的結果都是不一樣的。

一般傳統的MD5類方式加密密碼時,判斷輸入的密碼是否正确,就是重新用加密算法把密碼再加密一次,然後判斷加密的結果與資料庫中儲存的是否一緻。現在使用這樣的方式來校驗密碼自然是不行的了(注:ecshop和ectouch就是用這種方法存密碼的)。

PHP提供了password_verify()函數用來校驗密碼是否正确,這個函數有兩個參數,第一個是使用者輸入的密碼,第二個參數是事先儲存的密碼hash值。既然每次調用password_hash()的傳回值都不一樣,那password_verify()又是怎麼确認密碼是正确的呢?

根據PHP官網對于該函數的說明:

“注意 password_hash() 傳回的哈希包含了算法、 cost 和鹽值。 是以,所有需要的資訊都包含内。使得驗證函數不需要儲存額外鹽值等資訊即可驗證哈希。”

Yii 2提供了一個Security類,将上面的密碼加密和驗證函數封裝起來,并且增加了對于低版本PHP的支援。

generatePasswordHash

生成密碼的哈希值,調用password_hash()實作。

validatePassword

校驗密碼是否正确,調用password_verify()實作。

在架構中使用Security類,無需自己初始化,Yii 2架構已經預設建立了Security類的執行個體,使用如下代碼通路即可:

Yii::$app->security->validatePassword($password, $this->password_hash);

//或者

Yii::$app->getSecurity()->hashData(serialize([$cookie->name, $value]), $validationKey)

Security類的初始化?在base\Application.php中的preInit()函數中調用coreComponents()函數獲得所配置的security屬性對應的類路徑:

public function coreComponents()

 {

     return [

         'log' => ['class' => 'yii\log\Dispatcher'],

         'view' => ['class' => 'yii\web\View'],

         'formatter' => ['class' => 'yii\i18n\Formatter'],

         'i18n' => ['class' => 'yii\i18n\I18N'],

         'mailer' => ['class' => 'yii\swiftmailer\Mailer'],

         'urlManager' => ['class' => 'yii\web\UrlManager'],

         'assetManager' => ['class' => 'yii\web\AssetManager'],

         'security' => ['class' => 'yii\base\Security'],

     ];

 }

看Security類的代碼發現,其有一個compareString()函數,從功能上分析,它就是比較兩個字元串是否相等,但是為什麼不直接使用“==”來比較呢?看這個函數的說明:“Performs string comparison using timing attack resistant approach”。

這裡的“timing attack”(時序攻擊)引起了我的興趣,于是了解了一下,原來是有些破解算法是根據目标系統的運作時間,來推測出加密算法的一些資訊,進而降低破解難度,提高破解速度,真的是很有意思的一種破解思路。

參考文獻:

<a href="https://www.zhihu.com/question/20156213" target="_blank">如何通俗地解釋時序攻擊(timingattack)?</a>

本文轉自 tywali 51CTO部落格,原文連結:http://blog.51cto.com/lancelot/1871635,如需轉載請自行聯系原作者