RHE 7不尊重Java安全随机种子

时间:2018-04-30 20:46:43

标签: java rhel rhel7 secure-random

我的手上有一个窘境。我创建了一个AES服务来加密/解密敏感信息。 AES密钥是使用java SecureRandom随机生成的。我有一个存储种子的受保护文件,在调用服务时,种子被填充到安全随机类中。

为了确保它有效,我有以下逻辑:

private boolean secureRandom(final String seed) {
  SecureRandom sr1 = new SecureRandom(seed.getBytes(UTF8_CHARSET));
  SecureRandom sr2 = new SecureRandom(seed.getBytes(UTF8_CHARSET));
  //Two secure random with the same seed should generate the same results
  boolean secureRandomWorks = sr1.nextLong() == sr2.nextLong();
  if (!secureRandomWorks) {
    System.err.println("Secure random not supported. Defaulting to old key");
  }
  return secureRandomWorks;
}

这里的想法是我应该能够使用相同的种子创建两个安全的随机对象,并且在调用nextLong()时应该返回相同的值

当我在Windows机器上部署我的应用程序时,这很好用,但是当我在RHEL 7机器上部署它时,我得到了我的错误。

我的印象是,只要种子相同,两个实例将始终产生相同的输出。这似乎是在Windows上的情况,但是当我在RHEL 7上测试它时,情况似乎并非如此。

我创建了这个简单的测试以查看验证:

SecureRandom sr1 = new SecureRandom("encryptionKey".getBytes("UTF-8"));
SecureRandom sr2 = new SecureRandom("encryptionKey".getBytes("UTF-8"));

for (int i = 0; i < 1000; i++) {
  System.out.println(sr1.nextLong() == sr2.nextLong());
}

在Windows上,每个输出都是真的,而在RHEL 7上这是错误的。

关于什么可能导致RHEL 7忽略种子的任何想法?

2 个答案:

答案 0 :(得分:3)

我找不到任何禁止您在RHEL 7上观察到的行为的文档。

java.util.Random的JavaDoc明确说明

  

如果使用相同的种子创建了两个Random实例,并且为每个实例创建了相同的方法调用序列,则它们将生成并返回相同的数字序列

java.security.SecureRandom的JavaDoc不包含类似的声明。

相反,它提到(在setSeed()方法的文档中)

  

重新种植此随机对象。给定的种子补充而不是替代现有的种子。因此,保证重复呼叫永远不会减少随机性。

答案 1 :(得分:0)

事实证明,RHEL 7(以及一般的Linux机器)默认使用与Windows不同的算法。 Linux使用NativePRNG,而Windows使用SHA1PRNG

Linux使用内置/dev/random/dev/urandom并使用NativePRNG

考虑到这一点,我能够改变初始化SecureRandom对象的方式

private static final String ALGORITHM = "SHA1PRNG";
private static final String PROVIDER = "SUN";

private SecureRandom getSecureRandom(String seed) throws NoSuchAlgorithmException, NoSuchProviderException {
  SecureRandom sr = SecureRandom.getInstance(ALGORITHM, PROVIDER);
  sr.setSeed(seed.getBytes(UTF8_CHARSET));
  return sr;
}

从文档中getInstance不会为对象播种,因此它可以根据需要进行播种。

  

返回的SecureRandom对象尚未播种。播种   返回对象,调用setSeed方法。如果没有调用setSeed,   第一次调用nextBytes将强制SecureRandom对象播种   本身。如果先前使用setSeed,则不会发生这种自播种   调用。

现在它被迫使用我需要的东西,我不应该对RHEL 7有任何问题。