本文目錄一覽:
- 1、PBKDF2函數,比「Hash加鹽」更好的口令保護方案
- 2、為什麼OpenSSL的:PKCS5.pbkdf2
- 3、為什麼crypto.pbkdf2最後生成的密文長度是keylen的兩倍,而不是keylen的長度?
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。
稍微休息下,希望大家理解上述概念之間的區別。
KDF 本質上屬於 Key stretching、key strengthening,如果你了解 HTTPS,那麼可能比較熟悉,比如在握手階段,HTTPS 將 Premaster Secret 和客戶端服務器端的隨機數導出為 Master Secret,然後再將 Master Secret 導出為多個密鑰塊,這些密鑰塊包含 AES 的加密密鑰或者初始化向量,用戶後續通信數據的加密和完整性保護。
PBE 算法標準定義在 RFC 2898 文檔中,大概的公式如下:
如果 c 的數值越大,那麼運算速度就越慢,增加了時間複雜度,攻擊者破解的成功率就會下降。
使用 PHP 語言說明 PBKDF2 函數的使用:
對這個過程循環2000次,總共需要 16秒 ,而如果運行簡單的 Hash+salt,循環2000次,運行時間不到 0.1秒 。
從這個角度看,建議大家使用 PBKDF2 保護你的口令,但現在業界的保護口令的標準算法是 bcrypt ,下一篇文章會講解。
口令保護系列文章:
了解我的書 《深入淺出HTTPS:從原理的實戰》 ,如果覺得還不錯,還請在豆瓣上做個評論(地址: )。
為什麼OpenSSL的:PKCS5.pbkdf2
irb(main):029:0 iv = key_iv[cipher.key_len, cipher.iv_len]
= “`O\xF3\x94\n\xB5.y%_\xA3[\b\x16\x84\xB0”
irb(main):030:0 iv.length
= 16
irb(main):032:0 iv.each_char { |c| puts c.ord.to_s(16) }
60
4f
f3
94
a ### this one is missing in your number — it maps to \n
b5
2e
79
25
5f
a3
5b
8
16
84
b0
= “`O\xF3\x94\n\xB5.y%_\xA3[\b\x16\x84\xB0”
為什麼crypto.pbkdf2最後生成的密文長度是keylen的兩倍,而不是keylen的長度?
……你編程從來不看文檔的么?
A selected HMAC digest algorithm specified by digest is applied to derive a key of the requested byte length (keylen) from thepassword, salt and iterations.
已經明確說了,keylen 是字節長度,32字節的十六進制數值,用字符串表示當然就是64個字符……
原創文章,作者:YMPF,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/140060.html