我有一些 Java 代码,当我运行函数时KeyPairGenerator.genKayPair()
工作时间为 40 秒或更长时间。如何改变这种现状呢?如果我跑
openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout server.key -out cert.pem
3秒就可以了。慢速代码:
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
SecureRandom random = new SecureRandom();
gen.initialize(4096, random);
keyPair = gen.generateKeyPair();
PublicKey pubk = keyPair.getPublic();
PrivateKey prvk = keyPair.getPrivate();
首先,虽然 Java 在业务逻辑方面确实很快,但优化的 C 代码(其中重要的是汇编)在加密方面将使它大吃一惊。
Java会使用BigInteger
执行这些计算,并且BigInteger
- 并不总是包含针对所有功能的本机优化方法。注意Oracle JDK/OpenJDK发布此答案时已进行了一些更改 https://bugs.openjdk.java.net/browse/JDK-8191339?jql=text%20%7E%20%22biginteger%20intrinsics%22并且确实允许内在函数给几个人的BigInteger
方法,从 JDK 8 开始,包括蒙哥马利乘法。脚本语言通常比 Java 差得多,除非它们调用本机代码。
Java也需要时间来优化字节码。这意味着如果多次调用它,它的运行速度会更快。所以你至少需要先调用一个密钥生成器来看看会发生什么如果多次调用这样的方法在您的应用程序中。在这种情况下,运行时间可能会非常高,以至于它已经能够优化——这取决于虚拟机的实现。
RSA密钥的生成主要依赖于查找two大质数,其大小约为密钥大小的一半。查找大素数是一个 CPU 密集型过程。它还依赖于随机数生成器来创建起点。所以实际使用的随机数生成器实现有很大的不同 -尤其如果没有足够的熵可用,随机数生成器是否可以阻止。因此,请尝试使用可用的随机数生成器,直到找到一个足够快速且安全的随机数生成器。
查找特定长度的素数是一个没有指定运行时间的过程;这过程不是确定性的。选择一个非常大的数字(在本例中大约为 4096 / 2 = 2048 位)并开始测试后续数字是否为质数。这就是对 CPU 造成影响的原因。所以你需要计算average生成素数的运行时间 - 如果您生成很多素数 - 否则您将不得不忍受所需时间的不确定性。
但这有点没有实际意义。一般来说,您不需要大量 RSA 密钥 - 您可以为每个用户生成一到三个密钥。所以这只会在以下情况下成为问题:
- 你有很多用户
- 您有一个需要大量密钥对的协议或
- 你需要非常大的 RSA 密钥。
如果您想以更快的方式生成密钥对,您可以执行以下操作:
- 获取 Java 的本机实现
Provider
众所周知,速度很快,例如使用本机代码或专用硬件(例如 HSM);
- 切换到另一种密钥对生成速度快的算法,例如椭圆曲线密码术;
- 使用生成密钥
openssl
只需在 Java 应用程序中导入/使用它们即可。
通常,您需要修复协议而不是密钥对生成器。通常,您只使用不需要经常生成的静态密钥对(编辑:除了提供前向安全性的密钥建立外,但为此您通常使用(椭圆曲线)Diffie-Hellman,而不是 RSA)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)