当前位置: 首页 > 面试题库 >

使用NativePRNG和SHA1PRNG的SecureRandom

黄向明
2023-03-14
问题内容

我需要生成加密强度高的随机数和字节数组。为此,我使用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/randomor
/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处理即可。我没有看到明显的操作差异。

何时根本不使用SecureRandom

作为一般警告,我强烈建议不要将随机数生成器用于除随机数生成之外的任何操作。即使您可以自己播种它,甚至选择Sun的SHA1PRNG,
也不要指望能够从随机数生成器中提取相同的随机数序列 。因此,仅举一个例子, 不要 将其用于从密码派生密钥。

如果确实需要重复序列,则使用流密码,并将种子信息用于密钥和IV。加密由零组成的纯文本以检索伪随机值的密钥流。或者,您可以使用可扩展输出函数(XOF),例如SHAKE128或SHAKE256(如果有)。

您可能要考虑使用其他非安全的随机数生成器,而不是考虑SecureRandom是否可用的RNG不能提供足够的性能以及安全性不是问题。任何SecureRandom实现都不会像非安全随机数生成器(例如Mersenne
Twister算法或由Random该类实现的算法)那样快。已针对简单性和速度而非安全性对其进行了优化。

可以
_扩展SecureRandom类_并将确定的种子式随机实现插入到库调用中。这样库就可以检索具有良好定义的输出的伪随机数生成器。但是应该注意,算法可以以不同的方式使用随机数生成器。例如,RSA可能会切换到查找素数的更好的优化方法,并且可以使用已调整或直接计算的奇偶校验位生成DES密钥。



 类似资料:
  • java.util.regex 是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包。它包括两个类:Pattern 和 Matcher。 Pattern 对象是正则表达式编译后在内存中的表示形式,因此,正则表达式字符串必须先被编译为 Pattern 对象,然后再利用该 Pattern 对象创建对应的 Matcher 对象。执行匹配所涉及的状态保留在 Matcher 对象中,多个 Match

  • 问题内容: 我在让NEST的DeleteByQuery方法工作时遇到了一些困难。 很简单,查询永远找不到要删除的内容,我也不知道为什么。我正在使用相同的查询来返回记录(使用搜索),并且一切正常。 我只是刚刚开始使用NEST,所以我确定这是一个非常简单的问题,而且我有点昏暗! 任何帮助/建议,不胜感激。 问题答案: 的是上的.NET方法支票是否相等。 如果您更改对它的呼叫,则应该可以使用。

  • Serenity 平台使用了一些很有用的开源工具和库,列出如下(按字母顺序排列): 此列表可能看起来有点长,但一个 Serenity 的应用程序并没有依赖所有的库。 其中一些库只在 Serenity 平台自身的发展过程中才用到,而有一些是可选功能的依赖项。 我们尽量使用开源库,因为它们的优质可以避免重新造轮子。 Autonumeric (https://github.com/BobKnothe/a

  • 问题内容: 本教程演示了指令的使用,而不是: 他们要求: 用普通的旧src属性替换ng-src指令。 使用Firebug或Chrome的Web检查器之类的工具,或检查Web服务器的访问日志,确认该应用确实确实对 /app/%7B%7Bphone.imageUrl%7D%7D (或 / app / {{phone .imageUrl}} )。 我这样做了,它给了我正确的结果: 有什么原因吗? 问题答

  • 我不是XPATH方面的专家,我非常希望有一个解决方案,因为我正在用Windows应用程序自动化的Robot Framework做一些PoC工作。 多谢了。

  • 我使用以下方法从NodeJS中的crypto lib创建加盐和散列密码: 对于randomBytes调用(创建SALT)我应该使用多大的大小?我听说过128位的盐,可能最多256位。看起来这个函数使用的是字节大小,那么我可以假设32(256位)的大小就足够了吗? 对于pbkdf2调用,什么是好的迭代次数,什么是好的密钥长度(keylen)?