gpt4 book ai didi

cryptography - 使用Java 8u20进行慢速AES GCM加密和解密

转载 作者:行者123 更新时间:2023-12-03 11:56:05 65 4
gpt4 key购买 nike

我正在尝试使用AES / GCM / NoPadding加密和解密数据。我安装了JCE无限强度策略文件,并在下面运行了(简单思路)基准测试。我已经使用OpenSSL进行了相同的操作,并且能够在PC上实现 1 GB / s 加密和解密以外的功能。

使用下面的基准测试,我只能在同一台PC上使用Java 8获得 3 MB / s 加密和解密。知道我在做什么错吗?

public static void main(String[] args) throws Exception {
final byte[] data = new byte[64 * 1024];
final byte[] encrypted = new byte[64 * 1024];
final byte[] key = new byte[32];
final byte[] iv = new byte[12];
final Random random = new Random(1);
random.nextBytes(data);
random.nextBytes(key);
random.nextBytes(iv);

System.out.println("Benchmarking AES-256 GCM encryption for 10 seconds");
long javaEncryptInputBytes = 0;
long javaEncryptStartTime = System.currentTimeMillis();
final Cipher javaAES256 = Cipher.getInstance("AES/GCM/NoPadding");
byte[] tag = new byte[16];
long encryptInitTime = 0L;
long encryptUpdate1Time = 0L;
long encryptDoFinalTime = 0L;
while (System.currentTimeMillis() - javaEncryptStartTime < 10000) {
random.nextBytes(iv);
long n1 = System.nanoTime();
javaAES256.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new GCMParameterSpec(16 * Byte.SIZE, iv));
long n2 = System.nanoTime();
javaAES256.update(data, 0, data.length, encrypted, 0);
long n3 = System.nanoTime();
javaAES256.doFinal(tag, 0);
long n4 = System.nanoTime();
javaEncryptInputBytes += data.length;

encryptInitTime = n2 - n1;
encryptUpdate1Time = n3 - n2;
encryptDoFinalTime = n4 - n3;
}
long javaEncryptEndTime = System.currentTimeMillis();
System.out.println("Time init (ns): " + encryptInitTime);
System.out.println("Time update (ns): " + encryptUpdate1Time);
System.out.println("Time do final (ns): " + encryptDoFinalTime);
System.out.println("Java calculated at " + (javaEncryptInputBytes / 1024 / 1024 / ((javaEncryptEndTime - javaEncryptStartTime) / 1000)) + " MB/s");

System.out.println("Benchmarking AES-256 GCM decryption for 10 seconds");
long javaDecryptInputBytes = 0;
long javaDecryptStartTime = System.currentTimeMillis();
final GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(16 * Byte.SIZE, iv);
final SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
long decryptInitTime = 0L;
long decryptUpdate1Time = 0L;
long decryptUpdate2Time = 0L;
long decryptDoFinalTime = 0L;
while (System.currentTimeMillis() - javaDecryptStartTime < 10000) {
long n1 = System.nanoTime();
javaAES256.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);
long n2 = System.nanoTime();
int offset = javaAES256.update(encrypted, 0, encrypted.length, data, 0);
long n3 = System.nanoTime();
javaAES256.update(tag, 0, tag.length, data, offset);
long n4 = System.nanoTime();
javaAES256.doFinal(data, offset);
long n5 = System.nanoTime();
javaDecryptInputBytes += data.length;

decryptInitTime += n2 - n1;
decryptUpdate1Time += n3 - n2;
decryptUpdate2Time += n4 - n3;
decryptDoFinalTime += n5 - n4;
}
long javaDecryptEndTime = System.currentTimeMillis();
System.out.println("Time init (ns): " + decryptInitTime);
System.out.println("Time update 1 (ns): " + decryptUpdate1Time);
System.out.println("Time update 2 (ns): " + decryptUpdate2Time);
System.out.println("Time do final (ns): " + decryptDoFinalTime);
System.out.println("Total bytes processed: " + javaDecryptInputBytes);
System.out.println("Java calculated at " + (javaDecryptInputBytes / 1024 / 1024 / ((javaDecryptEndTime - javaDecryptStartTime) / 1000)) + " MB/s");
}

编辑:
我将其作为改善此简单基准的有趣练习。

我已经使用ServerVM进行了更多测试,删除了nanoTime调用并引入了预热,但是正如我所期望的那样,这些都没有对基准测试结果带来任何改善。它的线速度为每秒3 兆字节

最佳答案

除了微基准测试,JDK 8中的GCM实现(至少达到1.8.0_25)的性能受到损害。

我可以用更成熟的微基准持续地(在Haswell i7笔记本电脑上)再现3MB / s。

code dive来看,这似乎是由于幼稚的乘法器实现和GCM计算没有硬件加速引起的。

相比之下,JDK 8中的AES(以ECB或CBC模式)使用AES-NI加速的内在函数,并且(至少对于Java)非常快(在相同硬件上约为1GB / s),但是总体上AES / GCM性能完全由损坏的GCM性能决定。

plans to implement hardware accelerationthere have been third party submissions to improve the performance with,但是这些还没有发布。

还有一点需要注意的是,JDK GCM实现还会在解密时缓冲整个明文,直到密文末尾的身份验证标签得到验证为止,这会破坏它以用于大消息。

Bouncy CaSTLe具有(在撰写本文时)更快的GCM实现(如果您正在编写不受软件专利法约束的开源软件,则可以使用OCB)。

2015年7月更新-1.8.0_45和JDK 9

JDK 8+将获得改进的(并且是固定时间的)Java实现(由RedHat的Florian Weimer贡献)-它已经出现在JDK 9 EA构建中,但显然尚未出现在1.8.0_45中。
JDK9(至少从EA b72起)还具有GCM内部函数-b72上的AES / GCM速度为18MB / s(未启用内部函数)和25MB / s(已启用内部函数),两者都令人失望-相比之下,最快(不是恒定时间)的BC实现速度为〜60MB / s,最慢的(恒定时间,未完全优化)为〜26MB / s。

2016年1月更新-1.8.0_72:

JDK 1.8.0_60中提供了一些性能修复程序,并且在同一基准上的性能现在为18MB / s,比原始性能提高了6倍,但仍然比BC实现慢得多。

关于cryptography - 使用Java 8u20进行慢速AES GCM加密和解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25992131/

65 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com