關於加密密鑰大小的說明
給定具有特定密鑰大小(例如,64 位)的密鑰。我將其解釋為 8 個字元是否正確(因為在 ASCII 編碼下每個字元都是 8 位)?
由於 ASCII 方案僅限於 127 個字元,這意味著不考慮不包含在英語中的字元。是不是必鬚根據包含更多字元的編碼方案(例如 unicode)來解釋 64 位?– 這意味著 64 位包含的字元數量要少得多,因為 unicode 字元佔用更多位。
“字元”在這裡是錯誤的抽象級別,只關注它只會讓你誤入歧途。 正確的加密密鑰不是密碼!
- 密碼通常是人工選擇的,使用者可能需要記住它們。
- 密碼密鑰不能是人為選擇的!沒有好的密鑰是人類記憶的——您通常應該將密鑰作為副本保存在安全儲存(可能受密碼保護)下。
為什麼這個這麼重要?因為大多數加密算法都希望您從整個允許值範圍內隨機均勻地選擇密鑰。對於密鑰是固定長度位序列的算法,這意味著所需大小的任何位序列都應該與其他任何位序列一樣可能。
這意味著要生成加密密鑰**,您不能像密碼那樣要求人類選擇字元**,因為人類不擅長隨機性。相反,您必須使用加密安全的隨機數生成器來生成隨機選擇的原始字節數組。因此,要使用鍵,您應該遠離任何涉及字元編碼(如 ASCII 或 Unicode)的字元串類型,並學習如何在您選擇的程式語言中使用字節數組。例如在 Java 中,它是
byte[]
類型;在 Rust 中,它將是[u8]
(byte slice) 或[u8; N]
(byte array of sizeN
);在 C 中它會是char[]
(事後看來應該有不同名稱的類型);等等,或者更好的是,您應該使用一種抽像出來的類型,比如 JavaKeyGenerator
和SecretKey
.請注意,密鑰有時被序列化為 base-64 或十六進制 ASCII 字元串,但這只是一種格式,例如,將它們粘貼到不能接受任意字節的 JSON 等文件類型中。但是算法需要原始字節數組!
此外,還有一種稱為基於密碼的密鑰派生,它使用專門的密碼算法將使用者選擇的密碼轉換為偽隨機密碼密鑰。設計良好的密碼加密程序不會直接使用使用者提供的密碼作為密鑰,而是通過這樣的算法執行它們。這有時稱為“基於密碼的加密”。從密碼中獲取密鑰的流行算法有:
- https://en.wikipedia.org/wiki/PBKDF2
- https://en.wikipedia.org/wiki/Bcrypt
- https://en.wikipedia.org/wiki/Scrypt
請注意,這種方法以安全性換取使用者友好性。使用者發現密碼比正確的加密密鑰更容易(錯誤)使用和(錯誤)理解,但他們不太可能選擇與正確的、隨機生成的密鑰幾乎一樣強的密碼。(並且選擇同等強度密碼的極少數使用者可能足夠成熟以使用正確的密鑰!)