gpt4 book ai didi

java - 使用 Java 进行极其缓慢的内置 AES 加密

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:19:52 25 4
gpt4 key购买 nike

我有很多非常小的数据(19 字节)需要加密和发送通过 tcp 以加密格式发送到远程服务器。我正在使用下面的代码这样做。

package aesclient;

import java.io.OutputStream;
import java.net.Socket;

import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AESClient {
static byte[] plaintext = new byte[] {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53};
public static void main(String[] args) {
try {
Socket socket = new Socket("127.0.0.1", 1337); // connecting to server on localhost
OutputStream outputStream = socket.getOutputStream();
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
String s_key = "Random09" + "Random09"; // 16 Byte = 128 Bit Key
byte[] b_key = s_key.getBytes();
SecretKeySpec sKeySpec = new SecretKeySpec(b_key, "AES");
SecureRandom random = SecureRandom.getInstanceStrong();
byte[] IV = new byte[16]; // initialization vector
int num = 10000;
long start = System.nanoTime();
for (int i = 0; i < num; ++i) {
random.nextBytes(IV);
IvParameterSpec ivSpec = new IvParameterSpec(IV);
cipher.init(Cipher.ENCRYPT_MODE, sKeySpec, ivSpec);
byte[] msg = new byte[16 + 32];
System.arraycopy(IV, 0, msg, 0, IV.length);
byte[] encrypted = cipher.doFinal(plaintext);
System.arraycopy(encrypted, 0, msg, IV.length, encrypted.length);
outputStream.write(msg);
outputStream.flush();
}
long end = System.nanoTime();
long duration = end - start;
double drate = ((double)plaintext.length*(double)num)/((double)duration/1000000000);
System.out.println("Verschlüsselung:\n" + num + " mal 19 Bytes in " + ((double)duration/1000000000) + " s\nData Rate = " + drate/1000.0 + " kBytes/s");
}
catch (Exception e) {
System.err.println(e.getMessage());
}
}
}

我想知道为什么它非常慢。我得到这样的输出:

Verschlüsselung:
10000 mal 19 Bytes in 2.566016627 s
Data Rate = 74.04472675694785 kBytes/s

这意味着我的原始数据速率为 74 kByte/s(未加密)数据。如果我省略通过 TCP 发送,数据速率的增加可以忽略不计(那么大约是 100kByte/s)。我已经阅读了有关数据速率的信息20MByte/s 甚至更高。我有一台配备 Windows 10 和 i5 处理器的笔记本电脑。如果有任何帮助,我将不胜感激。正如我所说,我只需要转移很多加密的小数据包(19 字节)。

最佳答案

SecureRandom 即使在 PRNG 模式下也很慢,甚至在没有足够的熵可用时甚至会阻塞。

我建议获取随机 IV 一次,并在类似于 CTR 模式的迭代之间递增它。或者只使用 CTR 模式。

public class Test {
static byte[] plaintext = new byte[] { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
0x52, 0x53 };

public static void main(String[] args) {
try {
Cipher cipher = Cipher.getInstance("AES/CTR/PKCS5PADDING");
String s_key = "Random09" + "Random09"; // 16 Byte = 128 Bit Key
byte[] b_key = s_key.getBytes();
SecretKeySpec sKeySpec = new SecretKeySpec(b_key, "AES");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
byte[] IV = new byte[16]; // initialization vector
random.nextBytes(IV);
int num = 10000;
long start = System.nanoTime();
for (int i = 0; i < num; ++i) {
IvParameterSpec ivSpec = new IvParameterSpec(IV);
cipher.init(Cipher.ENCRYPT_MODE, sKeySpec, ivSpec);
byte[] msg = new byte[16 + 32];
System.arraycopy(IV, 0, msg, 0, IV.length);
byte[] encrypted = cipher.doFinal(plaintext);
System.arraycopy(encrypted, 0, msg, IV.length, encrypted.length);
increment(IV);
}
long end = System.nanoTime();
long duration = end - start;
double drate = ((double) plaintext.length * (double) num) / ((double) duration / 1000000000);
System.out.println("Verschlüsselung:\n" + num + " mal 19 Bytes in " + ((double) duration / 1000000000) + " s\nData Rate = " + drate
/ 1000.0 + " kBytes/s");
} catch (Exception e) {
System.err.println(e.getMessage());
}
}

private static void increment(byte[] iv) {
for (int i=0; i<4; ++i) {
if (++iv[i] != 0)
break;
}
}
}

打印:

Verschlüsselung:
10000 mal 19 Bytes in 0.0331898 s
Data Rate = 5724.650344382912 kBytes/s

在我的机器上至少快 30 倍。

关于java - 使用 Java 进行极其缓慢的内置 AES 加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53706907/

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