Java AES 加速

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3045520/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 00:05:42  来源:igfitidea点击:

AES acceleration for Java

javaencryptionaes

提问by Chris Lercher

I want to encrypt/decrypt lots of small (2-10kB) pieces of data. The performance is ok for now: On a Core2Duo, I get about 90 MBytes/s AES256 (when using 2 threads). But I may need to improve that in the future - or at least reduce the impact on the CPU.

我想加密/解密大量小(2-10kB)数据。目前性能还可以:在 Core2Duo 上,我得到大约 90 MBytes/s AES256(使用 2 个线程时)。但是我将来可能需要改进它——或者至少减少对 CPU 的影响。

  • Is it possible to use dedicated AES encryption hardware with Java (using JCE, or maybe a different API)?
  • Would Java take advantage of special CPU features (SSE5?!), if I get a better CPU?
  • Or are there faster JCE providers? (I tried SunJCE and BouncyCastle - no big difference.)
  • Other possiblilities?
  • 是否可以将专用的 AES 加密硬件与 Java(使用 JCE 或不同的 API)一起使用?
  • 如果我得到更好的 CPU,Java 会利用特殊的 CPU 特性(SSE5?!)吗?
  • 或者有更快的 JCE 提供者吗?(我尝试过 SunJCE 和 BouncyCastle - 没有太大区别。)
  • 其他可能性?

采纳答案by Thomas Pornin

The JVM will not, by itself, take advantage of special CPU features when executing code which happens to be an AES encryption: recognizing some code as being an implementation of AES is beyond the abilities of the JIT compiler. To use special hardware (e.g. the "Padlock" on VIA processors, or the AES-NIinstructions on the newer Intel processors), you must go, at some point, through "native code".

在执行恰好是 AES 加密的代码时,JVM 本身不会利用特殊的 CPU 功能:将某些代码识别为 AES 的实现超出了 JIT 编译器的能力。要使用特殊硬件(例如 VIA 处理器上的“挂锁”,或较新的 Intel 处理器上的AES-NI指令),您必须在某个时候通过“本机代码”。

Possibly, a JCE provider could do that for you. I am not aware of any readily available JCE provider which includes optimized native code for AES (there was a project called Apache JuiCE, but it seems to be stalled and I do not know its status). However it is conceivable that SunJCE will do that in a future version (but with Oracle buying Sun and the overfeaturism of OpenJDK 7, it is unclear when the next Java version will be released). Alternatively, bite the bullet and use native code yourself. Native code is invoked through JNI, and for the native AES code, a popular implementation is the one from Brian Gladman. When you get a bigger and newer processor with the AES-NI instruction, replace that native code with some code which knows about these instructions, as Intel describes.

可能,JCE 提供商可以为您做到这一点。我不知道有任何现成的 JCE 提供程序,其中包括用于 AES 的优化本机代码(有一个名为Apache JuiCE的项目,但它似乎停滞不前,我不知道它的状态)。但是可以想象,SunJCE 会在未来的版本中做到这一点(但由于 Oracle 收购了 Sun 以及 OpenJDK 7 的过度特性,下一个 Java 版本何时发布尚不清楚)。或者,硬着头皮自己使用本机代码。本机代码通过JNI调用,对于本机 AES 代码,一种流行的实现是来自Brian Gladman 的实现. 当您使用 AES-NI 指令获得更大、更新的处理器时,用一些了解这些指令的代码替换该本地代码,如英特尔所述

By using AES-128 instead of AES-256 you should get a +40% speed boost. Breaking AES-128 is currently beyond the technological reach of Mankind, and should stay so for the next few decades. Do you really need a 256-bit key for AES ?

通过使用 AES-128 而不是 AES-256,您应该获得 +40% 的速度提升。打破 AES-128 目前超出了人类的技术范围,并且应该在接下来的几十年里保持下去。您真的需要 AES 的 256 位密钥吗?

回答by user432024

Just in case people run into this. JAVA 8 now uses AES-NI. See this: AES-NI intrinsics enabled by default?

以防万一人们遇到这种情况。JAVA 8 现在使用 AES-NI。请参阅:默认情况下启用 AES-NI 内在函数?

回答by Peter ?tibrany

You can benefit from improved AES speeds by using SunPKCS11 security provider together with mozilla-nss library.

通过将 SunPKCS11 安全提供程序与 mozilla-nss 库结合使用,您可以从改进的 AES 速度中受益。

Setup is described at

设置描述于

回答by Justin

A simple google search will identify some JCE providers which claim hardware acceleration Solaris Crypto Framework. I have heard the break-even point is 4K (where under 4k its faster to perform using in JVM java providers).

一个简单的谷歌搜索将识别一些声称硬件加速Solaris Crypto Framework 的JCE 供应商。我听说盈亏平衡点是 4K(在 4k 以下,在 JVM java 提供程序中使用速度更快)。

I might look at using the NSSimplementation, it mighthave some compiler optimizations for your platform (and you can certainly build from source with them enabled); though I have not used it myself. The big benefit with hardware a provider is probably the fact that the keys canbe stored in hardware in a way that supports using them without exposing them to the OS.

我可能会考虑使用NSS实现,它可能对您的平台进行了一些编译器优化(并且您当然可以在启用它们的情况下从源代码构建);虽然我自己没用过。硬件提供者的最大好处可能是密钥可以以支持使用它们的方式存储在硬件中,而不会将它们暴露给操作系统。

Update:I should probably mention that the Keyczarsource had some helpful insight (somewhere in source or surrounding docs) about reducing the overhead for initializing the Cipher. It also does exactly what you want (see Encrypter), and seems to implement asynchronous encryption (using a thread pool).

更新:我可能应该提到Keyczar源代码有一些关于减少初始化密码的开销的有用见解(在源代码或相关文档中的某处)。它也完全符合您的要求(请参阅加密器),并且似乎实现了异步加密(使用线程池)。

回答by badpanda

I would also suggest using AES-128 rather than 256. If the code is loosely coupled, and is still around in however many years it takes for AES-128 to become archaic, my guess is that it will be much easier to update the encryption at that point (when hardware will be more powerful) than it would be to try to optimize performance via hardware now.

我还建议使用 AES-128 而不是 256。如果代码是松散耦合的,并且在 AES-128 变得过时需要很多年的时间里仍然存在,我的猜测是更新加密会容易得多那时(当硬件将更强大时)而不是现在尝试通过硬件优化性能。

Of course, that is assuming it is loosely coupled :D

当然,这是假设它是松散耦合的:D

回答by Kishor Prakash

Usually the step which consumes more time is Initiating the KeyGenerator.

通常消耗更多时间的步骤是启动 KeyGenerator。

KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256); // This step takes more time
KeyGenerator aesKey = keyGen.generateKey();

The way I solved it is by generating a pool of KeyGeneratorinstances before the server statup and reusing them for just for Key Generation

我解决它的方法是KeyGenerator在服务器启动之前生成一个实例池并将它们重用于密钥生成