JEP 123:可配置的安全随机数生成
概述
增强用于安全随机数生成的 API,使其能够配置为在指定的质量和响应性约束条件下运行。
动机
目前,JDK 的 SecureRandom
API 默认实现可以使用阻塞/非阻塞系统调用的混合方式,结合系统特性以及一些内部摘要算法来生成加密安全的随机数和种子值。虽然已经尽力在速度和随机性质量之间取得平衡,但这并不适用于所有人。如果用户尝试调整实现配置,文档可能会令人困惑(或有误),并且最终无法提供所需的灵活性。长期以来,熟悉安全随机数生成的专家们一直在呼吁一个更好、更灵活的解决方案。
对于那些不太熟悉该实现的人来说,主要的痛点是不理解为什么应用程序在 SecureRandom
操作期间可能会挂起,尤其是在 Linux 系统上。当前的默认配置从 Unix 伪文件 /dev/random
中获取种子材料,如果系统熵池中没有足够的数据可用,它将阻塞。虽然我们可能无法解决这个底层问题,但应该做出一些努力来帮助减轻这种影响。
最终,这些问题可能导致应用程序阻塞或生成熵不足的密钥,因此必须解决。多年来,通过一个没有很好记录的变通办法解决了若干升级问题,但易于配置的根本问题仍然存在。
关于仍然存在的混淆情况,请参见 bug 6202721 的评论部分,以此为例。
描述
随机数据对于许多加密结构和仿真系统至关重要。一些系统随机数生成器(例如 /dev/random
)能够提供非常高质量的随机数据(用于诸如长期存储密钥之类的用途),但必须阻塞直到获得足够的随机性为止。其他系统生成器(例如 /dev/urandom
)可以在不阻塞的情况下提供合理质量的随机性,这适用于生命周期较短的会话密钥。还有一些其他的伪随机数生成算法可以通过测量系统特征来获取随机数据。JDK 的 SecureRandom
提供者使用了这些技术的混合,但这也使得实现配置变得不必要地复杂且令人困惑,并且非常难以向开发者和客户解释。
有许多错误需要调查和/或解决:
- 6425477:更好地支持生成高熵随机数
- 6614946:
jre/lib/security/java.security
配置文件中的错误 - 6577564:添加关于可能阻塞
SecureRandom.generateSeed()/nextBytes()
的说明
取决于我们决定如何解决这些问题,它也可能解决:
- 6258213:请求包含
java.random
库
目前,尚不清楚如何最好地解决这些问题。在错误 6425477 中,提交者建议为 SecureRandom
添加一个名为 getTrueRandom
的新方法。这是一个选项,但并未解决配置问题。我们还可以使用类似新的 SecureRandom 算法名称(如 "TrueRandom
"、"NonBlockingRandom
"),或者添加新的 API 以支持算法特性或属性,例如:
sr = new SecureRandom( ..., SR_HIGHQUALITY|SR_NON_BLOCKING);
随着工作的进展,更多细节将被添加到本文档中。
测试
我们应该确保默认实现与当前发布的产品保持相似。此外,应测试每个配置,以确保记录在案的配置选项能够按宣传的那样工作。正确性测试可能会很困难,因为可能无法确定获得的数据是否真的来自所请求的源。
由于文件名不同,Windows 创建了一个特殊的随机文件名。因此,这需要在所有可用的平台上进行测试。
风险与假设
我们必须考虑向后兼容性。一些应用程序依赖于当前特定于实现的默认值(非阻塞数据、阻塞种子),在进行更改时需要考虑到这一点。
影响
- 其他 JDK 组件:任何需要
SecureRandom
数据的组件(例如,KeyGenerators
,SSL/TLS 和 Kerberos 等协议) - 文档:新机制需要被记录在文档中。