Java 9:AES-GCM性能 [英] Java 9: AES-GCM performance

查看:179
本文介绍了Java 9:AES-GCM性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经进行了一项简单的测试,以测量 AES-GCM Java 9 ,通过循环加密字节缓冲区来实现。结果有些令人困惑。本机(硬件)加速似乎有效-但并非总是如此。更具体地说,

I have run a simple test to measure the AES-GCM performance in Java 9, by encrypting byte buffers in a loop. The results were somewhat confusing. The native (hardware) acceleration seems to work - but not always. More specifically,


  1. 在循环中加密1MB缓冲区时,前约50秒的速度为〜60 MB / sec。然后它跳到1100 MB /秒,并保持在那里。 JVM是否决定在50秒(或3GB的数据)后激活硬件加速?可以配置吗?
    在哪里可以了解新的 AES-GCM 实现(在这里)。

  2. 加密100MB缓冲区时,硬件加速根本不起作用。速度是固定的60 MB /秒。

  1. When encrypting 1MB buffers in a loop, the speed is ~60 MB/sec for the first ~50 seconds. Then it jumps to 1100 MB/sec, and stays there. Does JVM decide to activate the hardware acceleration after 50 seconds (or 3GB of data)? can it be configured? Where can I read about the new AES-GCM implementation (besides here).
  2. When encrypting 100MB buffers, the hardware acceleration doesn't kick in at all. The speed is a flat 60 MB/sec.

我的测试代码如下:

int plen = 1024*1024;
byte[] input = new byte[plen];
for (int i=0; i < input.length; i++) { input[i] = (byte)i;}
byte[] nonce = new byte[12];
...
// Uses SunJCE provider
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
byte[] key_code = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
SecretKey key = new SecretKeySpec(key_code, "AES");
SecureRandom random = new SecureRandom();

long total = 0;
while (true) {
  random.nextBytes(nonce);
  GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, nonce);
  cipher.init(Cipher.ENCRYPT_MODE, key, spec);
  byte[] cipherText = cipher.doFinal(input);
  total += plen;
  // print delta_total/delta_time, once in a while
}

2019年2月更新:热点已修改为解决此问题。该修补程序适用于Java 13,也可以反向移植到Java 11和12。

Feb 2019 update: HotSpot had been modified to address this issue. The fix is applied in Java 13, and also backported to Java 11 and 12.

https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8201633 https://hg.openjdk.java.net/jdk/jdk/rev/f35a8aaabcb9

2019年7月16日更新:新发布的Java版本(Java 11.0.4)解决了此问题。

July 16, 2019 update: The newly released Java version (Java 11.0.4) fixes this problem.

推荐答案

感谢@Holger指出正确的方向。在 cipher.doFinal 前添加多个 cipher.update 调用将几乎立即触发硬件加速。

Thanks @Holger for pointing in the right direction. Prepending cipher.doFinal with multiple cipher.update calls will trigger the hardware acceleration almost immediately.

基于此参考, GCM分析 ,我在每次更新中都使用了 4KB 块。现在, 1MB 100MB 缓冲区均以 1100 MB /秒的速度(几十毫秒后 )进行加密。

Based on this reference, GCM Analysis , I'm using 4KB chunks in each update. Now both 1MB and 100MB buffers are encrypted at 1100 MB/sec speed (after a few dozen milliseconds) .

解决方案是替换

byte[] cipherText = cipher.doFinal(input);

int clen = plen + GCM_TAG_LENGTH;
byte[] cipherText = new byte[clen];

int chunkLen = 4 * 1024;
int left = plen;
int inputOffset = 0;
int outputOffset = 0;

while (left > chunkLen) {
  int written = cipher.update(input, inputOffset, chunkLen, cipherText, outputOffset);
  inputOffset += chunkLen;
  outputOffset += written;
  left -= chunkLen;
}

cipher.doFinal(input, inputOffset, left, cipherText, outputOffset);

这篇关于Java 9:AES-GCM性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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