jjzjj

java - SecureRandom.getInstance ("SHA1PRNG", "SUN") 总是阻塞而 new SecureRandom() 不是?

coder 2024-03-20 原文

我想咨询一些关于 Java 中 SecureRandom 的常见神话、安全与性能权衡的问题。

在网上查了一段时间,整理了以下资料。我希望这里的人能帮助我确认我得到了什么,并希望对实际选择实现的内容有一些想法。

基本上这里有一些关于 SecureRandom 的最受欢迎和最详尽的文章:

正确使用 Java 的 SecureRandom: https://www.synopsys.com/blogs/software-security/proper-use-of-javas-securerandom/

使用 Java 的 SecureRandom 时的问题: https://www.synopsys.com/blogs/software-security/issues-when-using-java-securerandom/

使用 SecureRandom 类: http://moi.vonos.net/java/securerandom/

并且,Sun 官方“承认”了错误/混淆以及在 Java 8 中提出的发布: http://openjdk.java.net/jeps/123

现在 Java 8 已经出来了,老实说,我不确定这个问题实际修复得有多好,仅通过查看文档: http://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html

所以毕竟,这就是我得到的(请帮我看看我是否对它们进行了排序):

像 Amit Sethi 这样的人建议使用指定的实例化,例如:SecureRandom sr3 = SecureRandom.getInstance("SHA1PRNG", "SUN"),实际上,Sun 告诉我们这最终总是从/dev/random(? ??),这意味着它可能会阻塞每个调用。与使用 new SecureRandom() 相反,除非调用 generateSeed() ,否则它将始终从/dev/urandom 读取。见

http://bugs.java.com/view_bug.do?bug_id=6202721

这是否意味着“new SecureRandom()”在当前 Java 中仍然是首选?我发现没有多少其他文档明确说明上述观点,所以我想知道这是否仍然正确?

现在,如果选择“new SecureRandom()”并将导致永不阻塞调用,那么我认为我应该为定期重新播种做些什么:

使 SecureRandom 成为类中的静态实例,并让另一个 Executor 线程定期对其调用 generateSeed(),因此即使调用被阻塞,它也不会影响我应用程序中的主请求处理线程。这听起来是个好方法吗?

非常感谢任何 Java 和加密专家在这里阐明这个问题。 谢谢!

编辑: 这里的另一个有用线程似乎支持我的猜测:https://bugs.openjdk.java.net/browse/JDK-4705093

最佳答案


编辑 :首先;如果 /dev/random/dev/urandom 阻塞,首先尝试修复该特定问题是有意义的。下面的解决方案是关于尝试修复 Java 本身的 SecureRandom,因此它不太依赖于那些特殊设备。


Make SecureRandom a static instance in the class and let another Executor thread periodically call generateSeed() on it, thus even though the call is blocking, it's not affecting my main request handling thread in my application. Does that sound like a good way doing it?

不,在这种情况下,您应该使用 nextBytes(),因为内部调用 generateSeed() 使用种子信息的原始供应商。换句话说,您也可以创建一个单独的 SecureRandom 实例。请注意,只要您有一个具有足够高状态和良好支持算法的 SecureRandom 实例,就不需要经常重新播种(因为它不太可能创建循环)。如果您需要更高的熵,每次都生成一个新的随机类或使用使用 SecureRandom.getInstanceStrong() 检索的随机数.

使用默认的 new SecureRandom() 可能是最好的。通常,您应该始终为加密算法提供精确的算法名称(例如 “AES/CBC/PKCS5Padding”),但对于安全的随机功能,最好让系统找出最佳算法。如果您想更改任何内容,请通过命令行结构进行更改,并确保 /dev/urandom 在 Unix 系统上可用。

如果您仍然遇到阻塞问题,请创建一个中央系统种子 SecureRandom。使用 nextBytes() 创建新的种子 Material ,并使用 SecureRandom(byte[] seed) 将其提供给新的 SecureRandom构造函数。仅当 new SecureRandom() 无法处理这种情况时才应使用此方法。

即使现在通过使用构造函数显式提供初始种子,构造函数本身也不能保证它仅用于为 RNG 播种。但是,可能确实是这种情况,因此不太可能阻止。 SecureRandom is thread safe所以你不需要同步访问它。

使用新的 Java 8 SecureRandom.getInstanceStrong() 更有可能阻塞。我假设他们添加了以使默认实例成为非阻塞。 RSA key 对生成通常需要大量熵,因此返回的实例很可能确实使用对 /dev/random 的阻塞调用。

总而言之,在特殊情况下使用 SecureRandom 仍然相当麻烦。幸运的是,这只是数量非常有限的用例的问题。

关于java - SecureRandom.getInstance ("SHA1PRNG", "SUN") 总是阻塞而 new SecureRandom() 不是?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23024107/

有关java - SecureRandom.getInstance ("SHA1PRNG", "SUN") 总是阻塞而 new SecureRandom() 不是?的更多相关文章

  1. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  2. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  3. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  4. ruby - 为什么 SecureRandom.uuid 创建一个唯一的字符串? - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?

  5. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  6. ruby-on-rails - 迷你测试错误 : "NameError: uninitialized constant" - 2

    我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test

  7. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  8. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  9. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

    当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

  10. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

随机推荐