哪種密碼生成方法可以提供更好的安全性?
我們想要生成可用作密碼的字元串(稍後儲存將使用 ex.: bcrypt 完成,但這些是字面意思的密碼)。
在 Linux 機器上,兩種生成方法是:
head -c 8192 /dev/urandom | md5sum | cut -d' ' -f1 head -c 8192 /dev/urandom | tr -cd '0123456789abcdef' | cut -c-32
**哪種方法提供“更多安全性”?**兩個輸出之間有什麼細微差別嗎?
我認為第二個可能會更好,因為它是“真正隨機的”。
第一個帶有 md5 (恕我直言)的不能比第二個更好,因為它使用雜湊,可能會發生衝突(機會非常低,但可能會發生)。
[user@notebook ~]$ head -c 8192 /dev/urandom | md5sum | cut -d' ' -f1 62ef651ded5c26dbc9cbc4194e60facd [user@notebook ~]$ head -c 8192 /dev/urandom | tr -cd '0123456789abcdef' | cut -c-32 c0fe36c50d4b9898fbf77be5f46bc375 [user@notebook ~]$
所以兩者都具有相同的長度,都使用相同的可用字元,都具有相同的隨機輸入。
我最近讀到有基於雜湊的隨機生成器:Hash-DRBG 所以不確定。
當然 pwgen 可以用來生成密碼,但問題是這兩種生成方法哪個更安全?
如果問題不是 100% 清楚,我可以調整它,請問。
看起來您正試圖跳過奇怪的圈子,只是將原始字節編碼為十六進制。您只是
md5sum
因為它的十六進制輸出的副作用而使用它,更糟糕的是,您正在發送 8192 個隨機字節tr
並盲目地希望從中獲得 32 個十六進製字元。為什麼不直接將 32 個隨機字節編碼為 16 個十六進制八位字節?
head -c16 /dev/urandom | xxd -p
理想的密碼是:
- **安全:**從足夠大的集合中以相等的機率隨機抽取;
- **可用:**人類很容易記住並輸入到他們的設備中。
這兩個目標不一致,但這是另一天的故事。那麼,對於您的問題,您需要回答您的提案中哪些部分有助於實現這兩個目標,哪些部分是多餘的。看著它:
/dev/urandom
以相等的機率進行隨機選擇,並且您從中讀取的字節數/dev/urandom
限制了進行這些隨機選擇的集合的大小。因此,從中提取足夠的字節/dev/urandom
將自行滿足#1。- 的輸出
/dev/urandom
是人類難以記憶和輸入的隨機字節。因此,您需要一種將這些隨機字節轉換為使用者友好的字母數字字元串的方法。該方法的唯一真正要求是它產生足夠數量的不同輸出,並且這些輸出中的任何一個與所有其他輸出一樣可能。md5sum
對這裡的安全沒有任何貢獻。它真正做的只是將隨機字節轉換為十六進製字元串,以一種複雜(但在其他方面可以接受)的方式。再加上 MD5 是一個損壞的散列函式這一事實,是一種很大的程式碼氣味。- 繪製 8,192 個隨機字節以刪除所有不是 ASCII 十六進制數字的字節是生成隨機十六進製字元串的一種極其低效的方法。它還具有產生少於您所瞄準的 32 個十六進制數字的非零機率。為什麼不直接繪製 16 個隨機字節並將它們編碼為十六進制呢?
因此,斯蒂芬擊敗我的命令是對您的建議的一個很大的簡化:
% head -c16 /dev/urandom | xxd -p 9538366b124dc25ca710e61865a16304
在我上面的#2之後,一種可能的改進是使用更緊湊的二進製到ASCII編碼,比如Base64(
=
刪除了尾隨符號):% head -c16 /dev/urandom |base64 |tr -d '=' fC7dOC2ewAsWg2YDBFGL8A
下一個改進:只需縮短密碼,這樣人們就不必輸入太多。如果你只畫 10 個隨機字節,那麼密碼就有 80 位熵,這比大多數現實生活中的使用者選擇的密碼要強得多。
% head -c10 /dev/urandom | base64 |tr -d '=' EaB08MDVprOHWw
另一個僅有助於記憶方面的改進是將隨機字節編碼為隨機密碼,就像在Diceware或著名的 XKCD 漫畫中一樣。
請注意,我的最終建議——使用 80 位熵而不是 128 位——在嚴格的數字術語中,不如你開始提出的建議安全。但這裡的關鍵哲學點是,設計只需要足夠安全,只要滿足合理的目標安全級別,超越它就沒有任何好處。如果有的話,實現“更高”安全性所需的較長密碼更難使用。但是以可用性為代價的安全通常是以安全為代價的。