簡體   English   中英

如何在Java中創建安全的隨機AES密鑰?

[英]How to create a secure random AES key in Java?

使用標准JDK在Java中生成安全隨機AES密鑰的推薦方法是什么?

在其他帖子中,我發現了這一點,但使用SecretKeyFactory可能是一個更好的主意:

KeyGenerator keyGen = KeyGenerator.getInstance("AES");
SecureRandom random = new SecureRandom(); // cryptograph. secure random 
keyGen.init(random); 
SecretKey secretKey = keyGen.generateKey();

如果答案包括解釋為什么它是生成隨機密鑰的好方法,那將是很好的。 謝謝!

我會使用您建議的代碼,但稍作簡化:

KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256); // for example
SecretKey secretKey = keyGen.generateKey();

讓提供者選擇計划如何獲得隨機性 - 不要定義可能不如提供者已經選擇的內容。

此代碼示例假設( 正如Maarten在下面指出的那樣 )您已將java.security文件配置為在列表頂部包含首選提供程序。 如果要手動指定提供程序,只需調用KeyGenerator.getInstance("AES", "providerName");

對於真正安全的密鑰,您需要使用硬件安全模塊 (HSM)來生成和保護密鑰。 HSM制造商通常會提供一個JCE提供商,使用上面的代碼為您完成所有密鑰生成。

使用KeyGenerator將是首選方法。 正如Duncan指出的那樣,我肯定會在初始化期間給出密鑰大小。 KeyFactory是一種應該用於預先存在的密鑰的方法。

好的,讓我們來看看這個細節。 原則上,AES密鑰可以具有任何值。 在(3)DES中沒有“弱鍵”。 也沒有任何具有特定含義的位,如(3)DES奇偶校驗位。 因此,生成密鑰可以像生成具有隨機值的字節數組一樣簡單,並在其周圍創建SecretKeySpec

但是您使用的方法仍然有優勢: KeyGenerator專門用於生成密鑰。 這意味着代碼可以針對這一代進行優化。 可以提高效率和安全性。 例如,它可以被編程為避免暴露密鑰的定時側信道攻擊。 請注意,清除任何保存密鑰信息的byte[]可能已經是一個好主意,因為它們可能泄漏到交換文件中(盡管如此可能是這種情況)。

此外,如上所述,並非所有算法都使用完全隨機密鑰。 因此,使用KeyGenerator可以更輕松地切換到其他算法。 更現代的密碼只接受完全隨機密鑰; 這被視為超過例如DES的主要好處。

最后,在我的情況下,最重要的原因是, KeyGenerator方法是在安全令牌(智能卡,TPM,USB令牌或HSM)中處理AES密鑰的唯一有效方式。 如果使用SecretKeySpec創建byte[] ,則密鑰必須來自內存。 這意味着密鑰可以放在安全令牌中,但無論如何密鑰都暴露在內存中。 通常,安全令牌僅適用於在安全令牌中生成或通過例如智能卡或關鍵儀式注入的密鑰。 KeyGenerator可以與提供程序一起提供,以便在安全令牌中直接生成密鑰。

正如Duncan的回答所示 :始終明確指定密鑰大小(和任何其他參數)。 不要依賴於供應商違約,因為這使它不清楚你的應用程序在做,每個供應商都可能有自己的缺省值。

在其他帖子中有很多好處。 這是我使用的:

Key key;
SecureRandom rand = new SecureRandom();
KeyGenerator generator = KeyGenerator.getInstance("AES");
generator.init(256, rand);
key = generator.generateKey();

如果你需要另一個隨機性提供程序,我有時會出於測試目的,只需用rand替換rand

MySecureRandom rand = new MySecureRandom();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM