Kry*_*ian 17 java encryption performance android cryptography
你可以跳到TL; DR
我们有一个应用程序,它强烈依赖于AES加密和解密.我们希望尽可能多地支持设备,但其中一些(特别是糟糕的平板电脑,我不仅仅是指中文无名,还有一些来自三星或联想的低端平板电脑)加密和解密速度很慢.
我们在我们的应用程序中使用了Android 23,我们能够确定某种级别,在这种级别之下,我们的应用程序根本不适合最终用户(他们必须等待太长时间才能显示内容).很多平板电脑我们不得不排除在我们的应用程序中使用,但是,我们能够忍受这一点.
最近我们的一些依赖项开始需要更新版本的Android.例如,我们想切换到Facebook Core SDK,而不是完整的Facebook SDK以节省一些空间.但这取决于Android支持包v25,我们将无法构建它,因为proguard拒绝处理源.
因此决定将项目转移到更新的Android.除了它对我们的加密/解密机制的性能影响之外,它还是非常顺利.突然间,它慢得多.平板电脑我们认为"工作得足够好"非常慢.
TL; DR
我已经开始调查从Android 23迁移到Android 26期间发生的事情,这会导致AES加密/解密性能大幅下降.
我已经创建了一个应用程序,它可以作为一种基准.通过简单的改变:
compileSdkVersion 23->26
targetSdkVersion 23->26
compile 'com.android.support:appcompat-v7:VERSION' 23.4.0 -> 26.+
性能下降是巨大的.
以下是其中一个平板电脑的示例结果:
Android 23: 136959 B/s
Android 26: 34419 B/s
Run Code Online (Sandbox Code Playgroud)
这几乎慢了4倍.我可以在我必须测试的所有设备上重现这些结果.当然,在新的高性能设备上,它几乎看不到,但在旧设备上,很明显.
我在网上搜索了有关此的任何细节,但我什么也没找到.我真的很感激有人能够对这个问题有所了解.
我真的希望我在某个地方犯了一个错误,但我找不到它.
对于加密/解密,我们使用SpongyCastle库.
我的Crypto Tester应用程序的源代码可以在GitHub上找到:https://github.com/krstns/cryptoTester
有master
Android 23配置的master_26
分支和Android 26配置的分支.
为了完整起见,我将在此处粘贴用于解密的方法:
/**
* Decrypt the given data with the given key
*
* @param data The data to decrypt
* @return The decrypted bytes
*/
public static byte[] decrypt(byte[] data, byte[] key, byte[] iv) {
if (key == null || iv == null) {
throw new AssertionError("DECRYPT: Key or iv were not specified.");
}
// make sure key is AES256
byte[] bookKeyData = new byte[32];
byte[] outBuf;
System.arraycopy(key, 0, bookKeyData, 0, key.length);
try {
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESFastEngine()));
cipher.init(false, new ParametersWithIV(new KeyParameter(bookKeyData), iv));
int outputSize = cipher.getOutputSize(data.length);
outBuf = new byte[cipher.getOutputSize(outputSize)];
int processed = cipher.processBytes(data, 0, data.length, outBuf, 0);
if (processed < outputSize) {
processed += cipher.doFinal(outBuf, processed);
}
return Arrays.copyOfRange(outBuf, 0, processed);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
哦,是的.我知道这是CBC,我知道为什么不应该使用等等.目前,它是故意的.这不是问题的主题,所以我们不要去那里.
您似乎直接使用 SpongyCastle。SpongyCastle 是 BouncyCastle (BC) 的 Android 版本。然而,BC 是加密算法和周围实用 API 的纯软件实现。
如果您确实想加快 AES 计算速度,您应该使用 Java Security API,例如使用javax.crypto.Cipher
类. 这将允许在支持它的平台上进行硬件加速和本机代码执行。一般来说,这将是所有平台,因为主要加密功能是使用较新平台上的 OpenSSL 库实现的。
一般来说,当所需的功能在所提供的加密提供程序中不可用时,建议仅使用 Bouncy Castle“轻量级”API(例如您正在使用的软件 AES 实现)。对于 AES/CBC 等算法来说,情况绝对不是这样。
目前,您的库依赖于 Bouncy Castle 实现的字节码执行,这要慢得多。另请注意,Bouncy Castle 不太喜欢调试环境,因此在测试性能时请确保它运行无延迟 - 如果可能的话,无需调试器支持。
归档时间: |
|
查看次数: |
1230 次 |
最近记录: |