为什么KeyPairGenerator.genKeyPair()这么慢 [英] Why KeyPairGenerator.genKeyPair() so slow

查看:474
本文介绍了为什么KeyPairGenerator.genKeyPair()这么慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些Java代码,当我运行功能KeyPairGenerator.genKayPair()时,它的工作时间为40秒或更长时间.如何改变这种状况?如果我运行

I have some Java code and when I run function KeyPairGenerator.genKayPair() it's work 40 seconds or more. How change this situation? If I run

openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout server.key -out cert.pem 

工作3秒钟.慢速代码:

it's work 3 seconds. The slow code:

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代码(带有汇编功能)会在需要时将其引爆.涉及到密码学.

First of all, although Java is certainly fast with regards to business logic, optimized C code (with assembly where it counts) will blow it out of the water when it comes to cryptography.

Java将使用BigInteger来执行这些计算,并且BigInteger-并不总是包含针对所有功能的本机优化方法.请注意,Oracle JDK/OpenJDK 发布此答案时进行了一些更改,并且确实允许 intrinsics 几种BigInteger方法,从JDK 8开始,包括蒙哥马利乘法.除非脚本语言调用本地代码,否则它们通常比Java差得多.

Java will use BigInteger to perform these calculations, and BigInteger - does not always contain a native optimized methods for all functionality. Note that Oracle JDK / OpenJDK has made several changes when this answer was posted and does allow intrinsics for several BigInteger methods, starting at JDK 8, including Montgomery multiplication. Scripting languages generally are much worse than Java unless they call native code.

Java还需要时间来优化字节码.这意味着,如果多次调用它,它将运行得更快.因此,您至少需要调用一个密钥生成器,才能查看如果在您的应用程序中多次调用这样的方法.在这种情况下,运行时间可能会很高,以至于它已经可以进行优化-这取决于VM的实现.

Java also needs time to optimize byte code. That means it runs faster if it is called multiple times. So you need to at least call one key gen before to see what happens if such a method is called multiple times in your application. In this case the runtime may be so high that it is already able to optimize - that depends on the VM implementation.

RSA密钥生成主要取决于找到两个大质数,它们的大小约为密钥大小的一半.查找大的素数是一个非常占用CPU的过程.它还取决于随机数生成器来创建起点.因此,实际使用的随机数生成器实现会产生很大的差异-尤其是,如果没有足够的熵,则随机数生成器会阻塞.因此,请尝试使用可用的随机数生成器,直到找到足够快速和安全的生成器为止.

RSA key generation depends mainly on finding two large primes that are about half the key size in size. Finding large primes is a very CPU intensive process. It also depends on the random number generator to create starting points. So the actual random number generator implementation used makes a lot of difference - especially if the random number generator can block if not enough entropy is available. So play around with the random number generators available until you find one that is fast and secure enough.

查找一定长度的素数是没有指定运行时的过程; 过程不是确定性的.选择一个非常大的数字(在这种情况下,大约为4096/2 = 2048位),然后开始测试后续数字是否为质数.这就是重击您的CPU的原因.因此,您需要计算生成素数的平均运行时-以防生成大量素数-否则您将不得不承受花费时间的不确定性.

Finding a prime of a certain length is a process that doesn't have a designated runtime; the process is not deterministic. A very large number is picked (in this case about 4096 / 2 = 2048 bits in size) and start testing if the subsequent numbers are prime. This is what hammers your CPU. So you need to calculate the average runtime of generating prime - in case you are generating a lot of them - or you will have to live with the uncertainty about the time it takes.

虽然这一切都没有实际意义.通常,您不需要大量的RSA密钥-每个用户生成一到三个.因此,这仅在以下情况下成为问题:

This is all a bit moot though. In general you don't need oodles of RSA keys - you generate one to three per user. So this only becomes a problem when:

  1. 您有很多用户
  2. 您有一个需要很多密钥对的协议,或者
  3. 您需要非常大的RSA密钥.

如果您想以更快的方式生成密钥对,可以做一些事情:

If you want to have a faster way of generating key pairs you can do a few things:

  1. 获取已知为快速的Java Provider的本机实现,例如使用本地代码或专用硬件(例如HSM)
  2. 切换到密钥对生成速度很快的另一种算法,例如椭圆曲线密码学;
  3. 使用openssl生成密钥,然后将其导入/使用在Java应用程序中.
  1. obtain a native implementation of a Java Provider that is known to be fast, e.g. using native code or specialized hardware such as a HSM;
  2. switch to another algorithm for which key pair generation is fast, such as Elliptic Curve Cryptography;
  3. generate the keys using openssl and just import/use them in your Java application.

通常,您需要修复协议而不是密钥对生成器.通常,您只使用不需要经常生成的静态密钥对.

Usually though you would need to fix the protocol instead of the key pair generator. Normally you only use static key pairs that do not need to be generated very often.

这篇关于为什么KeyPairGenerator.genKeyPair()这么慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆