我们正在使用与 java 安装捆绑在一起的 keytool 来生成密钥以进行非对称 RSA 加密。鉴于最近发生的事件,有人问我 java keytool 的幕后发生了什么。特别是关于结果数字的随机性。(例如“嗯,为什么没有像鼠标移动或键盘输入这样的随机用户输入?”
那么创建密钥的 java keytool 的“随机源”是什么?
我自己做了一个快速的研究,但我发现的唯一信息是 2000 年的一篇文章:
- keytool.exe 使用 SecureRandom 作为其随机数的基础。
- SecureRandom 的 Sun 提供程序遵循 IEEE P1363 标准,
- Sun SecureRandom 提供程序符合 NIST 的 FIPS PUB 140-1 第 4.11 节。
- 用于 SecureRandom 的 Sun 提供程序将其他熵源与线程争用过程的结果混合在一起。其中包括当前时间、VM 内存使用状态、系统属性和文件系统活动。
- 该算法在没有 JIT 的情况下可能表现不佳,因此我们正在考虑提供替代提供商,该提供商将利用平台特定的对熵收集设备的支持,例如 /dev/random 或 Pentium III 热噪声 RNG。
但这又回到了 2K,所以你们中的某个人可能会对此有所了解并提供对上述内容的更新(在 Java7 中不同?)。根据您的回答,如果您建议切换到其他提供商,例如 bouncycastle,我会很感兴趣...
更新:我现在假设 keytool 使用 java.security.SecureRandom (因此是默认提供程序)作为其随机数的基础。我发现了另一篇有趣的文章,它指向了控制 SecureRandom API JAVA_HOME/lib/security/java.security 配置的文件
在那里它陈述了以下内容:
选择 SecureRandom 的种子数据源。默认情况下,尝试使用由 securerandom.source 属性指定的熵收集设备。如果访问 URL 时发生异常,则使用传统的系统/线程活动算法。在 Solaris 和 Linux 系统上,如果指定了 file:/dev/urandom 并且它存在,则默认激活特殊的 SecureRandom 实现。这个“NativePRNG”直接从 /dev/urandom 读取随机字节。在 Windows 系统上,URL 文件:/dev/random 和文件:/dev/urandom 允许使用 Microsoft CryptoAPI 种子功能。
securerandom.source=文件:/dev/urandom
由于我们使用的是 Windows 系统,因此我假设使用了Microsoft CryptoAPI。由于使用的是 Win7,因此它是 CNG(下一代 CryptoAPI)。有谁知道“使用 Microsoft CryptoAPI 种子功能”。方法?最可能的方法似乎是:CryptGenRandom function
更新:Oracle 似乎改进了Java 8的一些问题。