我们正在使用与java安装捆绑在一起的keytool生成密钥,以进行非对称RSA加密。鉴于最近发生的事件,有人问我在java keytool的引擎盖下发生了什么。特别是关于结果数字的随机性。(例如,“为什么没有任何随机的用户输入,比如鼠标移动或键盘输入?”
那么,java keytool创建密钥的“随机性来源”是什么呢?
我自己做了一个快速的调查,但我发现的唯一信息是2000年的一篇帖子:
但是这是在2K,所以也许你们中的某个人可以对此有所了解,并提供对上述内容的更新(不同于Java7?)。根据你的回答,如果你建议切换到另一个提供商,比如bouncyCastle,我会很感兴趣...
更新:我现在假设keytool使用的是java。安全SecureRandom(以及默认的提供者)作为其随机数的基础。我找到了另一篇有趣的文章,它指向了控制SecureRandom API JAVA_HOME/lib/security/JAVA配置的文件。安全
其中规定如下:
选择SecureRandom的种子数据源。默认情况下,会尝试使用securerandom.source属性指定的熵收集设备。如果在访问URL时发生异常,则使用传统的系统/线程活动算法。在Solaris和Linux系统上,如果指定了file:/dev/urandom并且它存在,则默认情况下会激活特殊的SecureRandom实现。此“NativePRNG”直接从 /dev/urandom.读取随机字节在Windows系统上,URL文件:/dev/Anywhere和file:/dev/urandom允许使用Microsoft CryptoAPI种子功能。
securerandom.source=file:/dev/urandom
因为我们是在windows系统上,所以我假设使用的是Microsoft CryptoAPI。因为使用的是Win7,所以它是CNG(CryptoAPI下一代)。有人知道“使用Microsoft CryptoAPI种子功能”是什么意思吗?最可能的方法似乎是:CryptGenRandom函数
更新:Oracle似乎改善了Java8的一些问题。
实际上,波鸿大学的Michaelis,Meyer,Schwenk发表了一篇论文,对Java中的随机性进行了更深入的分析。它被称为“随机失败”。它并没有给Java实现打上最好的分数,但它似乎不太警觉。
请注意,Java 8对JEP123做了一些改进(但是它仍然缺少使用更具弹性算法(如Fortuna)的RNG)。您可以在OpenJDK安全开发列表中看到关于JEP123的一些讨论:
看起来,除了这里记录的高级API的细节之外,实现可能是特定于平台(Windows/Linux)和JDK实现(OpenJDK/OracleJDK)。您可以在这里看到NativePRNG(在Linux上使用)的OpenJDK实现的源代码。
也许可以考虑使用bouncyCastle提供商来提高跨平台的透明度和一致性。
我想在这里分享我的发现:
>
keytool.exe使用SecureRandom作为其随机数的基础,可以在其源代码中看到:Keyool和CertAndKeyGen。
通常,正如SecureRandom API所述:“加密强随机数至少符合FIPS 140-2《加密模块的安全要求》第4.9.1节中规定的统计随机数生成器测试。”因此,SecureRandom的所有实现都应符合FIPS-140-2。
安全提供程序(也适用于SecureRandom)的配置是在JAVA_HOME/lib/Security/java.security
中完成的。默认值是(列表顶部):security.provider.1=sun.security.provider.Sun
不改变的时候3。)在Linux上,SecureRandom的默认实现是NativePRNG,而在Windows上,默认实现是SHA1PRNG。在我们的例子中,是windows pc生成密钥,因此它是SHA1PRNG
。
在实施过程中,以下几点尤为突出:
“请注意,如果未提供种子,我们将尝试提供足够的种子字节,以完全随机发生器的内部状态(20字节)。然而,我们的种子生成算法尚未得到彻底研究或广泛部署。”
SeedGenerator(所有SHA1PRNG SecureRandom对象的单例)的种子源顺序如下:
现在在SHA1PRNG中发现了以下问题:
>
统计偏差II(第1页)
“本文的实验结果表明,伪随机生成器SHA1PRNG(Java)产生的序列可以以高概率与均匀选择的序列区分开来。”
较差的差异(第12页)和有限的州规模(第9页)
“随机字节在STS测试、失败的单位测试、运行测试和前八个串行测试中有严重困难。这表明单位和八位元组的差异很小。”以及“在Java中增加更多的熵”(
结果是:
因此,可以假设Java密钥生成机制(至少在windows上)已损坏。因此,大多数作者建议使用一些硬件,比如HSM/TRNG。
我正在尝试用Java编写一个简单的密码管理器。我想用AES 256位加密用存储的密码加密文件。此外,我希望用户能够解密的文件与密码。当阅读其他在线帖子时,他们几乎都强调简单地使用密码作为密钥是不安全的,他们提到使用随机盐来增加安全性。但我不明白如何在生成密钥时使用随机盐。如果我从用户的密码和随机的salt创建密钥,那么当他们试图解密他们的文件时,我怎么知道salt是什么呢?这让我完全糊涂了。 目前
我正在尝试创建一个公钥以允许我推送到Git,但我的. ssh文件夹尚未创建。 以下是我运行的命令: $ssh-keygen-t rsa-Cemaill@me.com 生成公共/私有rsa密钥对 输入保存密钥的文件(/h/.ssh/id\u rsa): 这就是H:驱动器配置、数据、配置文件、配置文件中的全部内容。V2 我认为有一个问题,因为当我得到提示输入文件,其中保存密钥(/h//. ssh/id
如果我在某个地方出错,请纠正我,因为我是加密领域的新手。 我使用以下命令在Java 7中生成EC密钥对: 根据:文件。神谕com/javase/7/docs/technotes/tools/windows/keytool。html#命令 keytools-genkey对-alias MyServerPair-keyalg EC-keysize 571-sigalg SHA512 with ECDS
我正在开发一个将文件上传到Azure存储的.NET应用程序。我正在利用https://azure.microsoft.com/en-us/documentation/articles/storage-encrypt-decrypt-blobs-key-vault/教程中所做的客户端加密 应用程序工作,即,我可以成功地上传一个加密的blob到一个选定的存储帐户和容器。 但是,我对RSA密钥的安全性有
我有这样的情况,我使用OpenSSL生成了一个公钥/私钥对,供gdcmanon使用,遵循他们网站上列出的说明。具体地说,我使用以下命令为gdcmanon生成密钥 然后,我就能够按照他们的指示,加密一个文件,使用 这在c.init(cipher.decrypt_mode,key)行失败; 我已经为Java6安装了JCE(我正在使用)。我不知道我做错了什么。谁能给我指出正确的方向吗。 谢谢
提纲ceph-create-keys [-h] [-v] [–cluster name] –id id 描述 ceph-create-keys 工具用于在指定监视器可用时、生成自举引导密钥环。 它可以创建以下认证项目(或用户): client.admin 以及用于客户端的密钥 client.bootstrap-{osd, rgw, mds} 以及用于自举引导相应服务的密钥。 要罗列此集群内的所有用