生成相同的随机SecretKey两次

时间:2009-10-05 11:06:14

标签: java security random

我需要在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。也许我正在尝试的东西永远不会起作用(我知道这看起来像是一件奇怪的事情......)但如果有办法的话,我真的很感激,如果有人能告诉我这是什么方式!

3 个答案:

答案 0 :(得分:3)

即使 为您工作,您也不会真正拥有“秘密”密钥 - 您将拥有一个完全可从主机名派生的密钥。这不是秘密 - 就像每个人都使用他们的名字作为他们的密码。任何想要攻击加密数据的人只需要知道创建密钥的机器的名称,然后他们就可以访问。

密钥的最终形式几乎与重新创建密钥所需的信息无关。为了使密钥有效,基本上这些信息必须是秘密的。

答案 1 :(得分:3)

您无法生成两次随机密钥,因为它是随机的。

如果InetAddress.getLocalHost()。getHostName()足够独特,可以计算哈希值并将其用作键。正如Jon所说,关键是任何知道实现的人都可以得到。

答案 2 :(得分:3)

有两种方法可以通过编程方式保护密钥:

  • 保持密钥本身的秘密,或
  • 保持算法的秘密。

密码学家(和常识)会告诉你,在这两者中,第二个的安全性要差得多,因为对代码进行反向工程相对容易。所以你留下了第一种方法。

如果我正确地阅读了您的要求,您需要一个

的密钥
  1. 保证每台机器都是独一无二的。
  2. 随机。
  3. 不存储在任何地方。
  4. 可重复(通过您的软件)。
  5. 但是不可能满足所有这些。例如,无法随意存储任何未存储在任何地方(作为数据或嵌入在算法中)的真正随机密钥。因此,如果我可以采取一些余地,我会阅读您的用例并替换这些不那么严格的要求:

    1. 绑在主机上:一台机器的钥匙不能在另一台机器上使用。
    2. 安全:不太可能重复,猜测,反向设计,
    3. 安全:不太可能在您的计划中被发现。
    4. 可重现:您的应用程序必须能够根据需要重新生成密钥。
    5. 除了#3之外,所有这些新要求都可以通过以下步骤满足:


      1. 生成将在每台计算机上使用的秘密随机种子
      2. 选择每个主机唯一的机器相关签名,并将其附加到种子。典型示例是MAC地址,但在具有两个或更多NIC的计算机上,每次都必须小心使用相同的NIC!
      3. Hash结果与算法(如SHA)一样,会产生相当独特且不可逆转的结果。

      4. 现在剩下的就是满足第三个要求,让攻击者难以猜测必须保密的一个项目:种子。这就是这个过程变得更具宗教性而非技术性的论点,因为“相当困难”取决于攻击者想要发现密钥的严重程度以及他/她成功时的风险。

        为了尽可能安全,密钥必须存储在您的应用程序之外,例如在您的大脑中,并在每次需要时提供。但通常通过默默无闻机制的某种形式的较弱的安全性是可以接受的;我最喜欢的一个是使用0x%-6.2d之类的内容,可能会被忽略为printf()格式。如果您是偏执狂,请将其存储在碎片中并在应用程序的一部分中重新创建,否则该部分与密钥处理模块无关。

        如果您想了解更具体的建议,请告诉我们您的申请及其使用案例。

        祝你好运!