我想知道哪种是在0-255范围内生成高度安全的随机数的最佳方法,而且具有快速性能。它来到我,我肯定必须使用SecureRandom类,但我不确定我是否必须使用.getInstance(SHA1PRNG)或更好地让它默认没有arg构造函数。
我介于这两个选择之间:
第一种方式
public class RandomGenerator {
private static final String sha1prng = "SHA1PRNG";
private final SecureRandom csprng;
private final byte[] bytes = new byte[1];
public RandomGenerator() {
try {
csprng = SecureRandom.getInstance(sha1prng);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
csprng.nextBoolean();
}
protected int generateByte() {
do {
csprng.nextBytes(bytes);
} while (bytes[0] == 0);
return ((byte)(bytes[0] & 0xff) + 256) % 256;
}
}
第二道:
public class SomethingThatNeedsRandomBytes {
private static final int NUMBER_OF_RANDOM_BYTES = ... ;
private final SecureRandom csprng;
SomethingThatNeedsRandomBytes(SecureRandom csprng) {
if (csprng == null)
throw new IllegalArgumentException();
this.csprng = csprng;
}
void doSomethingInvolvingRandomness() {
byte[] bytes = new byte[NUMBER_OF_RANDOM_BYTES];
csprng.nextBytes(bytes);
// Do something with random bytes here.
}
}
我在这些网站上看到了很多其他答案,其中大多数建议不要使用SHA1PRNG并让它默认但另一方面其他一些答案建议使用NativePRNG(我不喜欢它,因为它不快)或SHA1PRNG。我想得到一个反馈,哪种方式可以生成高安全随机数,哪种方法最快。
提前致谢。
答案 0 :(得分:0)
使用空构造函数,SecureRandom将选择第一个支持SecureRandom算法的已注册安全提供程序;如果不存在,则默认为SHA1PRNG。这取决于系统,如果您的应用程序可能在不同的环境中运行,则应在构造函数中指定算法。要检索SecureRandom的安全提供程序的顺序,您可以运行以下命令:
import java.security.Security;
import java.security.Provider;
import java.security.Provider.Service;
for (Provider provider : Security.getProviders()) {
for (Service service : provider.getServices()) {
if (service.getType().equals("SecureRandom")) {
System.out.println(service.getAlgorithm());
}
}
}
NativePRNG的实现取决于操作系统,但通常使用硬件或操作系统事件生成的熵来生成随机值。通常,这必须等待在返回值之前生成熵。从绝对意义上说,这比SHA1PRNG更安全;但是,实际上你不太可能注意到这种差异。如果算法的速度对于应用程序很重要,则SHA1PRNG通常比NativePRNG更快,并且两种算法都为加密操作提供足够随机的值。应该注意的是,对于密码散列等应用程序,通常首选较慢的算法。
请参阅:https://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html#SecureRandom--