Java:摆脱 `Cipher.init()` 开销
Java: Get rid of `Cipher.init()` overhead
我需要提高以下方法的性能:
private byte[] decrypt(final byte[] encrypted, final Key key) throws ... {
this.cipher.init(Cipher.DECRYPT_MODE, key);
return this.cipher.doFinal(encrypted);
}
cipher
对象("AES/ECB/NoPadding")在构造函数中被初始化,这样就可以重用了。使用 ECB 是因为 encrypted
数组将始终只包含 16 个字节的数据(即 1 个数据块)。使用 128 位密钥。
此方法被调用数百万次以解密 16 字节块,每次都使用不同的密钥。例如。该方法是这样调用的:
final List<Key> keys = List with millions of keys
final byte[] data = new byte[] { ... 16 bytes of data go here ...}
for (final Key key : keys) {
final byte[] encrypted = decrypt(data, key);
// Do something with encrypted
}
Cipher.init()
占用了 decrypt
方法的大部分时间,因为数据非常小。 IE。超过 1200 万次调用,Cipher.init()
平均需要 3 微秒,而 Cipher.doFinal()
平均需要 < 0.5 微秒。
- 为什么
Cipher.init()
需要这么长时间?
- 有什么方法可以仅使用 Java 来加速这段代码吗?例如,利用我将始终只解密单个数据块的事实?
- 使用 C/C++ 实现并使用 JNI 调用它会更快吗?如果是这样,是否有任何完善的图书馆?
我使用 JDK 1.8.0_73 并且我的处理器支持 AES-NI.
What takes so long in Cipher.init()?
在初始化期间,用户提供的密钥数据被扩展为加密和解密例程使用的会话密钥。
Is there any way to speed up this code using Java only? For instance by taking advantage of the fact I will be decrypting always only a single block of data?
是的,但这需要重写 AES 算法的基本部分。您可以在 AESCrypt.java.
的 JDK 来源中找到它
或者,您可以存储预初始化密码列表而不是密钥。
Would it be faster to use a C/C++ implementation and call it using JNI? If so, is there any well-established library for that?
很有可能,是的。 libcrypto
是 OpenSSL 的一部分会有所帮助。 Here is an example.
我需要提高以下方法的性能:
private byte[] decrypt(final byte[] encrypted, final Key key) throws ... {
this.cipher.init(Cipher.DECRYPT_MODE, key);
return this.cipher.doFinal(encrypted);
}
cipher
对象("AES/ECB/NoPadding")在构造函数中被初始化,这样就可以重用了。使用 ECB 是因为 encrypted
数组将始终只包含 16 个字节的数据(即 1 个数据块)。使用 128 位密钥。
此方法被调用数百万次以解密 16 字节块,每次都使用不同的密钥。例如。该方法是这样调用的:
final List<Key> keys = List with millions of keys
final byte[] data = new byte[] { ... 16 bytes of data go here ...}
for (final Key key : keys) {
final byte[] encrypted = decrypt(data, key);
// Do something with encrypted
}
Cipher.init()
占用了 decrypt
方法的大部分时间,因为数据非常小。 IE。超过 1200 万次调用,Cipher.init()
平均需要 3 微秒,而 Cipher.doFinal()
平均需要 < 0.5 微秒。
- 为什么
Cipher.init()
需要这么长时间? - 有什么方法可以仅使用 Java 来加速这段代码吗?例如,利用我将始终只解密单个数据块的事实?
- 使用 C/C++ 实现并使用 JNI 调用它会更快吗?如果是这样,是否有任何完善的图书馆?
我使用 JDK 1.8.0_73 并且我的处理器支持 AES-NI.
What takes so long in Cipher.init()?
在初始化期间,用户提供的密钥数据被扩展为加密和解密例程使用的会话密钥。
Is there any way to speed up this code using Java only? For instance by taking advantage of the fact I will be decrypting always only a single block of data?
是的,但这需要重写 AES 算法的基本部分。您可以在 AESCrypt.java.
的 JDK 来源中找到它或者,您可以存储预初始化密码列表而不是密钥。
Would it be faster to use a C/C++ implementation and call it using JNI? If so, is there any well-established library for that?
很有可能,是的。 libcrypto
是 OpenSSL 的一部分会有所帮助。 Here is an example.