我想加密/解密许多小的(2-10kB)数据。现在性能还可以:在Core2Duo上,我得到大约90 MBytes / s的AES256(当使用2个线程时)。但是我可能需要在将来改进它 - 或者至少减少对CPU的影响。
答案 0 :(得分:13)
当执行恰好是AES加密的代码时,JVM本身不会利用特殊的CPU功能:将某些代码识别为AES的实现超出了JIT编译器的能力。要使用特殊硬件(例如VIA处理器上的“挂锁”或新英特尔处理器上的AES-NI指令),您必须在某个时候通过“本机代码”。
可能JCE提供商可以为您做到这一点。我不知道任何现成的JCE提供程序,其中包括针对AES的优化本机代码(有一个名为Apache JuiCE的项目,但它似乎停滞不前,我不知道它的状态)。但是可以想象,SunJCE将在未来的版本中实现这一点(但是由于Oracle购买Sun和OpenJDK 7的过度使用,目前还不清楚下一个Java版本何时发布)。或者,咬紧牙关并自己使用本机代码。通过JNI调用本机代码,对于本机AES代码,一种流行的实现是来自Brian Gladman的实现。当您使用AES-NI指令获得更大更新的处理器时,请使用一些知道这些指令的代码替换该本机代码,如Intel describes。
通过使用AES-128代替AES-256,您应该获得+ 40%的速度提升。打破AES-128目前超出了人类的技术范围,并且应该在未来几十年保持这种状态。你真的需要一个256位密钥用于AES吗?
答案 1 :(得分:10)
以防人们遇到这种情况。 JAVA 8现在使用AES-NI。请参阅:AES-NI intrinsics enabled by default?
答案 2 :(得分:7)
通过将SunPKCS11安全提供程序与mozilla-nss库一起使用,您可以从提高的AES速度中受益。
设置
答案 3 :(得分:4)
一个简单的谷歌搜索将识别一些声称硬件加速Solaris Crypto Framework的JCE提供商。我听说盈亏平衡点是4K(在4k以下,在JVM java提供程序中使用它的速度更快)。
我可能会考虑使用NSS实现,可能为您的平台进行一些编译器优化(并且您当然可以在启用它们的情况下从源代码构建);虽然我自己没有用过它。硬件和服务提供商的最大好处可能是,密钥可以以支持使用它们的方式存储在硬件中,而不会将它们暴露给操作系统。
更新:我应该提一下,Keyczar来源有一些有用的见解(在源或周围文档的某处)有关减少初始化密码的开销。它也完全符合你的要求(参见Encrypter),似乎实现了异步加密(使用线程池)。
答案 4 :(得分:1)
我还建议使用AES-128而不是256.如果代码是松散耦合的,并且在AES-128变得陈旧的情况下仍然存在很多年,我的猜测是,它会更容易此时更新加密(当硬件功能更强大时),而不是现在尝试通过硬件优化性能。
当然,这是假设松散耦合:D
答案 5 :(得分:0)
通常,消耗更多时间的步骤是启动KeyGenerator。
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256); // This step takes more time
KeyGenerator aesKey = keyGen.generateKey();
我解决问题的方法是在服务器配置之前生成KeyGenerator
个实例池,并将它们重新用于密钥生成