首先,尽管 Java 在业务逻辑方面确实很快,但优化的 C 代码(在其重要的地方包含汇编)将在涉及密码学时将其从水中吹走。
Java 将使用BigInteger
来执行这些计算,并且BigInteger
- 并不总是包含针对所有功能的本机优化方法。请注意,Oracle JDK / OpenJDK在发布此答案时进行了一些更改,并且确实允许从 JDK 8 开始的多种方法的内在函数BigInteger
,包括蒙哥马利乘法。脚本语言通常比 Java 差得多,除非它们调用本机代码。
Java 也需要时间来优化字节码。这意味着如果多次调用它,它会运行得更快。因此,您至少需要先调用一个密钥生成器,然后才能查看如果在您的应用程序中多次调用此类方法会发生什么。在这种情况下,运行时间可能会很高,以至于它已经能够优化——这取决于 VM 的实现。
RSA 密钥生成主要取决于找到两个大小约为密钥大小一半的大素数。寻找大素数是一个非常占用 CPU 资源的过程。它还依赖于随机数生成器来创建起点。因此,实际使用的随机数生成器实现会产生很大的不同——尤其是如果没有足够的熵可用,随机数生成器会阻塞。因此,请使用可用的随机数生成器,直到找到足够快速和安全的随机数生成器。
寻找一定长度的素数是一个没有指定运行时间的过程;该过程不是确定性的。选择一个非常大的数字(在这种情况下,大小约为 4096 / 2 = 2048 位)并开始测试后续数字是否为素数。这就是锤击你的 CPU 的原因。所以你需要计算生成素数的平均运行时间——以防你生成很多素数——否则你将不得不忍受它所花费的时间的不确定性。
不过,这一切都没有实际意义。一般来说,您不需要大量的 RSA 密钥——您为每个用户生成一到三个。所以这只会在以下情况下成为问题:
- 你有很多用户
- 您有一个需要大量密钥对的协议或
- 您需要非常大的 RSA 密钥。
如果您想以更快的方式生成密钥对,您可以执行以下操作:
- 获得
Provider
已知速度快的 Java 的本机实现,例如使用本机代码或专用硬件(如 HSM);
- 切换到另一种密钥对生成速度较快的算法,例如椭圆曲线密码术;
- 使用生成密钥
openssl
并在您的 Java 应用程序中导入/使用它们。
通常虽然您需要修复协议而不是密钥对生成器。通常您只使用不需要经常生成的静态密钥对(编辑:除了提供前向安全性的密钥建立,但您通常会使用(椭圆曲线)Diffie-Hellman,而不是 RSA)。