首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java 9: AES-GCM性能

Java 9: AES-GCM性能
EN

Stack Overflow用户
提问于 2018-02-21 11:55:24
回答 4查看 2.3K关注 0票数 12

我已经运行了一个简单的测试,通过在循环中加密字节缓冲区来度量AES-GCMJava9中的性能。结果有点令人困惑。本机(硬件)加速似乎起作用了--但并非总是如此。更确切地说,

  1. 在一个循环中加密1MB缓冲区时,第一个~50秒的速度是~60 MB/秒。然后它跳转到1100 MB/秒,并停留在那里。JVM决定在50秒(或3GB的数据)之后激活硬件加速吗?它可以配置吗?我在哪里可以读到新的AES-GCM实现(除了这里)。
  2. 在加密100 at缓冲区时,硬件加速根本不起作用。速度是60 MB/秒。

我的测试代码如下所示:

代码语言:javascript
复制
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月更新: HotSpot已被修改以解决此问题。修复在Java 13中应用,也支持Java 11和12。

id=JDK-8201633https://hg.openjdk.java.net/jdk/jdk/rev/f35a8aaabcb9

2019年7月16日更新:新发布的版本(Java11.0.4)修复了这个问题。

EN

回答 4

Stack Overflow用户

发布于 2018-02-22 09:55:18

谢谢霍格指出了正确的方向。预先使用多个cipher.doFinal调用的cipher.update将几乎立即触发硬件加速。

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

解决办法是替换

代码语言:javascript
复制
byte[] cipherText = cipher.doFinal(input);

使用

代码语言:javascript
复制
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);
票数 10
EN

Stack Overflow用户

发布于 2018-04-12 11:50:33

关于这个问题的几个更新。

  1. 3月底发布的Java 10也有同样的问题,可以用相同的方法绕过--仅用于数据加密
  2. 这种解决方案基本上不适用于数据解密--在Java9和Java 10中都是如此。

我已经向Java平台提交了一个bug报告。它被评价并作为JDK-8201633出版。

票数 3
EN

Stack Overflow用户

发布于 2019-02-14 06:59:37

这个问题在Java 13中得到了解决,修复也被移植到Java 11和12中。

id=JDK-8201633https://hg.openjdk.java.net/jdk/jdk/rev/f35a8aaabcb9

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48905291

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档