我们使用与 java 安装捆绑在一起的 keytool 来生成密钥以进行非对称 RSA 加密。鉴于近期events https://www.schneier.com/blog/archives/2013/09/the_nsa_is_brea.html有人问我 java keytool 的底层发生了什么。特别是关于结果数字的随机性。 (例如,“呃,为什么没有像鼠标移动或键盘输入这样的随机用户输入?”
那么 java keytool 创建密钥的“随机源”是什么?
我自己做了一个快速的研究,但是我发现的唯一信息是post http://www.mail-archive.com/cryptography@c2.net/msg03141.html从 2000 年开始:
- keytool.exe 使用 SecureRandom 作为其随机数的基础。
- Sun 的 SecureRandom 提供商遵循 IEEE P1363 标准,
- Sun SecureRandom 提供程序符合 NIST 的 FIPS PUB 140-1 第 4.11 节。
- Sun 的 SecureRandom 提供程序将其他熵源与线程争用过程的结果混合在一起。除其他外
这包括当前时间、虚拟机内存状态
使用情况、系统属性和文件系统活动。
- 在没有 JIT 的情况下,该算法可能会表现不佳,因此我们正在考虑提供一个替代提供商,该提供商将采取
对熵收集设备的平台特定支持的优势
例如 /dev/random 或 Pentium III 热噪声 RNG。
但这是在 2K 中出现的,所以你们中的某个人可能会对此有所了解并提供对上述内容的更新(Java7 中有所不同?)。根据您的回答,如果您建议切换到像 bouncycastle 这样的其他提供商,我会很感兴趣......
Update:
我现在假设 keytool 使用 java.security.SecureRandom (因此是默认提供程序)作为其随机数的基础。我发现另一个有趣的article http://resources.infosecinstitute.com/random-number-generation-java/,它向我指出了控制 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 和 file:/dev/urandom
允许使用 Microsoft CryptoAPI 种子功能。
securerandom.source=文件:/dev/urandom
由于我们使用的是 Windows 系统,我假设微软加密API http://en.wikipedia.org/wiki/Microsoft_CryptoAPI用来。由于Win7使用的是CNG(CryptoAPI Next Generation)。有谁知道“Microsoft CryptoAPI 种子功能的用途”是什么。方法?最可能的方法似乎是:CryptGenRandom function http://msdn.microsoft.com/en-us/library/aa379942%28VS.85%29.aspx
Update: Oracle 似乎已经改善了一些问题Java 8 https://docs.oracle.com/javase/8/docs/technotes/guides/security/enhancements-8.html.