使用NativePRNG和SHA1PRNG的SecureRandom
我需要生成加密强度高的随机数和字节数组。为此,我使用Java的SecureRandom
类。但是我不确定根据加密强度选择哪种PRNG算法。
以下哪个实例产生了更不可预测的数字?还是相等?
SecureRandom nativePrng = SecureRandom.getInstance("NativePRNG")SecureRandom sha1Prng = SecureRandom.getInstance("SHA1PRNG")
此外,我们能够使用“ SUN”提供程序生成这些实例(例如SecureRandom.getInstance("SHA1PRNG",
"SUN"))。这有什么不同吗?
提前致谢。
回答:
TL; DR:new
SecureRandom()不确定时使用,让系统找出来。可能SecureRandom.getInstanceStrong()
用于长期密钥生成。
不要期望随机数生成器会在运行时应用程序中生成特定的输出序列,即使您自己为它播种也是如此。
对于随机数生成器,总是很难说出最好的。Linux和大多数Unixes都考虑了周全的随机数生成器,因此使用/dev/random
or
/dev/urandom
,也不会造成损害"NativePRNG"
。使用的问题/dev/random
是它阻塞直到有足够的熵可用为止。因此,除非您对密钥生成有一些特殊要求,否则我将建议您这样做。
"SHA1PRNG"
使用哈希函数和计数器以及种子。该算法相对简单,但是没有被很好地描述。通常认为它是安全的。由于它在启动期间仅来自系统生成器之一,因此需要较少的内核调用,因此资源占用可能更少-
在我的系统上,它的运行速度比"NativePRNG"
(配置为使用/dev/urandom
)的快9倍。两者似乎都只对我的双核Ubuntu笔记本电脑的一个内核起作用(一次,它经常从一个内核切换到另一个内核,这可能归咎于内核调度)。如果您需要高性能,请选择此一项,尤其/dev/urandom
是在特定系统配置中设备运行缓慢时。
请注意,"SHA1PRNG"
目前在 阿帕奇和谐的实现是从一个在Sun提供者(在标准的Java
SE实现中使用由Oracle)不同。Jakarta中的版本也用于较旧的Android版本。尽管我无法进行完整的审查,但它看起来并不十分安全。
编辑:我不是这个半错, SHA1PRNG已经证明不是伪随机的版本<4.2.2多在这里。
要注意的是"SHA1PRNG"
是 对Java SE的实现要求。在大多数运行时中都会显示它,但是直接从代码中引用它会使代码的可移植性降低。
如今(从Java 9开始),OpenJDK和Oracle
JDK也包含简单地称为的多个实现"DRBG"
。这实现了由NIST在SP-108中指定的动态随机位生成器列表。这些也不是Java实现要求。但是,如果需要符合FIPS的随机数生成器,可以使用它们。
但是,他们不会在此处更改建议。如果开发人员认为这些比默认实现更好,那么他们只需将其设置为默认即可。的合同SecureRandom
不变:只需生成随机数即可。过去已经对默认算法进行了更改。
通常,也不要求有一个特定的提供者。指定提供商可能会损害互操作性;例如,并非每个Java运行时都可以访问SUN提供程序-
Android当然没有。这也使您的应用程序在运行时的灵活性降低,即您不能将提供程序放在列表的上方,而只能使用它。
因此,如果您依赖提供程序所提供的功能之一,请仅指明提供程序。例如,如果您具有生成随机数的特定硬件设备,或者已通过FIPS认证的加密库,则可能要指定提供程序。如果必须指定提供程序,最好为应用程序将算法/提供程序配置为一个选项。
未指定提供程序的想法也出现在此Android开发人员安全博客中。
因此,请尝试避免选择任何特定的随机生成器。相反,只需使用空参数构造函数即可:new
SecureRandom()让系统选择最佳的随机数生成器。SecureRandom.getInstanceStrong()
如果您对长期密钥生成有任何特定要求,则可以使用Java
8及更高版本中的新可配置项。
不要缓存的实例SecureRandom
,只需让它们初始设置种子并让VM处理即可。我没有看到明显的操作差异。
作为一般警告,我强烈建议不要将随机数生成器用于除随机数生成之外的任何操作。即使您可以自己播种它,甚至选择Sun的SHA1PRNG,
也不要指望能够从随机数生成器中提取相同的随机数序列 。因此,仅举一个例子, 将其用于从密码派生密钥。
如果确实需要重复序列,则使用流密码,并将种子信息用于密钥和IV。加密由零组成的纯文本以检索伪随机值的密钥流。或者,您可以使用可扩展输出函数(XOF),例如SHAKE128或SHAKE256(如果有)。
您可能要考虑使用其他非安全的随机数生成器,而不是考虑SecureRandom
是否可用的RNG不能提供足够的性能以及安全性不是问题。任何SecureRandom
实现都不会像非安全随机数生成器(例如Mersenne
Twister算法或由Random
该类实现的算法)那样快。已针对简单性和速度而非安全性对其进行了优化。
可以
_扩展SecureRandom
类_并将确定的种子式随机实现插入到库调用中。这样库就可以检索具有良好定义的输出的伪随机数生成器。但是应该注意,算法可以以不同的方式使用随机数生成器。例如,RSA可能会切换到查找素数的更好的优化方法,并且可以使用已调整或直接计算的奇偶校验位生成DES密钥。
以上是 使用NativePRNG和SHA1PRNG的SecureRandom 的全部内容, 来源链接: utcz.com/qa/427132.html