2

我手上有一个难题。我创建了一个 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 忽略种子的任何想法的建议?

4

2 回答 2

5

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

java.util.Random明确声明的 JavaDoc

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

JavaDoc forjava.security.SecureRandom不包含类似的语句。

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

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

于 2018-04-30T21:10:48.347 回答
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 有任何问题。

于 2018-05-01T13:01:36.927 回答