PBKDF2函數,比「Hash加鹽」更好的口令保護方案

在前面兩篇文章中,對用戶口令進行加密的方式其實稱為 Password-based encryption (PBE),算法實現很簡單,那是不是有更好和更標準的 PBE 實現呢?

基于 Hash+salt 的算法最大的問題在于 Hash 函數的運算太快了,雖然加鹽讓暴力攻擊和彩虹表攻擊的可行性大大減低,但現在攻擊者能在非??焖俚挠布ò?GPU)上運行,如果時間足夠,還是有很大幾率完成暴力破解。

那有沒有更好的解決方案嗎?如果讓口令運算運算的慢一點,那么攻擊者破解的速度也將上不去,這樣是否就能更好的保護明文口令?

在密碼學中,key derivation function (KDF) 函數非常重要,它可以通過一個 master key(在 HTTPS 中用的非常多)、口令(password)、passphrase(密碼學隨機數生成器)生成一個或多個強壯的密鑰,這些密鑰本身被密碼學算法使用(比如 AES、RSA 等等)。

用戶的口令通過 PBF(前兩篇文章講解的算法實現)生成的口令密文不是密鑰,所以最終結果不是用于密碼學用途,是為了避免口令被破解,但本質上 BPF 算法也可以通過 KDF 函數實現,也就是利用 KDF 函數生成口令密文。

KDF 同樣基于 Hash 函數,也有 salt 機制,當然最重要的是有迭代因子這個概念,有了迭代因子,會讓處理速度變慢,減少爆破風險。

KDF 主要有三種實現,分別是PBKDF2、bcrypt、scrypt,這篇文章主要討論 PBKDF2。

稍微休息下,希望大家理解上述概念之間的區(qū)別。

KDF 本質上屬于 Key stretching、key strengthening,如果你了解 HTTPS,那么可能比較熟悉,比如在握手階段,HTTPS 將 Premaster Secret 和客戶端服務器端的隨機數導出為 Master Secret,然后再將 Master Secret 導出為多個密鑰塊,這些密鑰塊包含 AES 的加密密鑰或者初始化向量,用戶后續(xù)通信數據的加密和完整性保護。

PBE 算法標準定義在 RFC 2898 文檔中,大概的公式如下:

DK = PBKDF2(PRF, Password, Salt, c, dkLen)
  • PRF 是一個偽隨機函數,可以簡單的理解為 Hash 函數。
  • Password 表示口令 。
  • Salt 表示鹽值,一個隨機數。
  • c 表示迭代次數。
  • dkLen 表示最后輸出的密鑰長度。

如果 c 的數值越大,那么運算速度就越慢,增加了時間復雜度,攻擊者破解的成功率就會下降。

使用 PHP 語言說明 PBKDF2 函數的使用:

$password = '明文口令';
// 隨機的鹽值
$salt = openssl_random_pseudo_bytes(12);
$keyLength = 40;
$iterations = 10000;
$generated_key = openssl_pbkdf2($password, $salt, $keyLength, $iterations, 'sha256');
//轉換為 16 進制
echo bin2hex($generated_key)."\n";

對這個過程循環(huán)2000次,總共需要16秒,而如果運行簡單的 Hash+salt,循環(huán)2000次,運行時間不到0.1秒。

從這個角度看,建議大家使用 PBKDF2 保護你的口令,但現在業(yè)界的保護口令的標準算法是 bcrypt ,下一篇文章會講解。

口令保護系列文章:


了解我的書《深入淺出HTTPS:從原理的實戰(zhàn)》,如果覺得還不錯,還請在豆瓣上做個評論(地址:https://book.douban.com/subject/30250772/)。

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容