我需要在Java中生成一个随机的SecretKey,我将在以后的某个时间点重新生成它。这个想法是这个密钥对于创建它的机器是唯一的,并且不存储在任何地方。我正在尝试这样的事情:
KeyGenerator keyGen = KeyGenerator.getInstance("DESede");
String hostname = InetAddress.getLocalHost().getHostName();
SecureRandom random = new SecureRandom(hostname.getBytes());
keyGen.init(random);
secretKey = keyGen.generateKey();
显然,这不起作用,因为设置SecureRandom的种子不会像我想象的那样工作,每次我得到一个不同的SecretKey。也许我正在尝试的东西永远不会起作用(我知道这看起来像是一件奇怪的事情......)但如果有办法的话,我真的很感激,如果有人能告诉我这是什么方式!
答案 0 :(得分:3)
即使 为您工作,您也不会真正拥有“秘密”密钥 - 您将拥有一个完全可从主机名派生的密钥。这不是秘密 - 就像每个人都使用他们的名字作为他们的密码。任何想要攻击加密数据的人只需要知道创建密钥的机器的名称,然后他们就可以访问。
密钥的最终形式几乎与重新创建密钥所需的信息无关。为了使密钥有效,基本上这些信息必须是秘密的。
答案 1 :(得分:3)
您无法生成两次随机密钥,因为它是随机的。
如果InetAddress.getLocalHost()。getHostName()足够独特,可以计算哈希值并将其用作键。正如Jon所说,关键是任何知道实现的人都可以得到。
答案 2 :(得分:3)
有两种方法可以通过编程方式保护密钥:
密码学家(和常识)会告诉你,在这两者中,第二个的安全性要差得多,因为对代码进行反向工程相对容易。所以你留下了第一种方法。
如果我正确地阅读了您的要求,您需要一个
的密钥但是不可能满足所有这些。例如,无法随意存储任何未存储在任何地方(作为数据或嵌入在算法中)的真正随机密钥。因此,如果我可以采取一些余地,我会阅读您的用例并替换这些不那么严格的要求:
除了#3之外,所有这些新要求都可以通过以下步骤满足:
现在剩下的就是满足第三个要求,让攻击者难以猜测必须保密的一个项目:种子。这就是这个过程变得更具宗教性而非技术性的论点,因为“相当困难”取决于攻击者想要发现密钥的严重程度以及他/她成功时的风险。
为了尽可能安全,密钥必须存储在您的应用程序之外,例如在您的大脑中,并在每次需要时提供。但通常通过默默无闻机制的某种形式的较弱的安全性是可以接受的;我最喜欢的一个是使用0x%-6.2d
之类的内容,可能会被忽略为printf()
格式。如果您是偏执狂,请将其存储在碎片中并在应用程序的一部分中重新创建,否则该部分与密钥处理模块无关。
如果您想了解更具体的建议,请告诉我们您的申请及其使用案例。
祝你好运!