AES acceleration for Java

后端 未结 6 1407
遥遥无期
遥遥无期 2020-12-03 10:47

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 m

相关标签:
6条回答
  • 2020-12-03 11:13

    Usually the step which consumes more time is Initiating the 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 KeyGenerator instances before the server statup and reusing them for just for Key Generation

    0 讨论(0)
  • 2020-12-03 11:20

    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.

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

    0 讨论(0)
  • 2020-12-03 11:23

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

    Setup is described at

    • Improved Advanced Encryption Standard (AES) Crypto performance on Java with NSS using Intel® AES-NI Instructions
    • and JavaTM PKCS#11 Reference Guide
    0 讨论(0)
  • 2020-12-03 11:28

    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).

    I might look at using the NSS implementation, it might have 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 can be stored in hardware in a way that supports using them without exposing them to the OS.

    Update: I should probably mention that the Keyczar source 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).

    0 讨论(0)
  • 2020-12-03 11:36

    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-NI instructions on the newer Intel processors), you must go, at some point, through "native code".

    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.

    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 ?

    0 讨论(0)
  • 2020-12-03 11:38

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

    0 讨论(0)
提交回复
热议问题