首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么AES在Android 24+上的加密/解密速度比3倍慢?

为什么AES在Android 24+上的加密/解密速度比3倍慢?
EN

Stack Overflow用户
提问于 2017-10-16 06:55:55
回答 2查看 2.8K关注 0票数 17

你可以跳到TL;博士

我们有一个应用程序,它非常依赖AES加密和解密。我们希望支持尽可能多的设备,但其中一些设备(尤其是糟糕的平板电脑-我指的不仅仅是中文名称,还有一些三星( Samsung )或联想( Lenovo)的低端平板电脑)的加密和解密速度很慢。

我们已经在我们的应用程序中使用了Android 23,我们能够识别出某种级别,在这种水平以下,我们的应用程序对最终用户来说将无法很好地工作(他们需要等待太长时间才能显示内容)。这是很多平板电脑,我们不得不排除在我们的应用程序使用,但好吧,我们能够接受这一点。

最近,我们的一些依赖项开始需要更新版本的Android。例如,我们希望切换到Facebook,而不是完整的Facebook,以节省一些空间。但是它依赖于Android支持包v25,我们将无法构建它,因为pro卫兵拒绝处理源代码。

于是决定将这个项目转移到一个新的Android系统上。除了它对我们的加密/解密机制产生的性能影响之外,它进行得相当顺利。突然间,速度慢了很多。我们认为“工作足够好”的平板电脑速度非常慢。

TL;博士

我已经开始研究从Android 23到Android 26的迁移过程中发生了什么,这将导致AES加密/解密的性能大幅下降。

我已经创建了一个应用程序,它可以作为一个基准。通过简单的改变:

  • compileSdkVersion 23->26
  • targetSdkVersion 23->26
  • compile 'com.android.support:appcompat-v7:VERSION' 23.4.0 -> 26.+

性能下降幅度很大。

下面是其中一个平板电脑的结果:

代码语言:javascript
复制
Android 23: 136959 B/s
Android 26: 34419 B/s

差不多慢了4倍。我可以在我必须测试的所有设备上重现这些结果。当然,在新的、高性能的设备上,它几乎看不见,但在旧设备上,它是明确的。

我在网上搜索过这方面的任何细节,但没有发现任何细节。我真的很希望有人能对这个问题有所了解。

我真希望我在某个地方犯了一个错误,但我没能找到。

对于加密/解密,我们使用SpongyCastle库。

我的Crypto应用程序的源代码可以在GitHub:https://github.com/krstns/cryptoTester上找到。

有安卓23配置的master分支和安卓26配置的master_26分支。

为了完整起见,我将在这里粘贴用于解密的方法:

代码语言:javascript
复制
/**
 * 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;
}

哦还有..。是。我知道这是CBC,我知道为什么它不应该使用等等。目前,它是故意的。这不是问题的主题,所以我们不要去那里。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-19 14:10:07

您似乎正在直接使用SpongyCastle。SpongyCastle是BouncyCastle (BC)的安卓版本。然而,BC是一个软件实现的密码算法和周围实用程序API的。

如果您真的想加快AES计算的速度,您应该使用Java,例如使用 class。这将允许在支持它的平台上进行硬件加速和本机代码执行。通常,这将是所有平台,因为主要的加密功能是在新平台上使用OpenSSL库实现的。

通常,当所提供的密码提供程序中没有所需的功能时,建议只使用B儿GY城堡“轻量级”API(例如您正在使用的软件AES实现)。这绝对是,而不是算法,例如AES/CBC。

目前,您的库依赖于Bouncy城堡实现的字节代码执行,这要慢得多。还请注意,Bouncy城堡不太喜欢调试环境,所以在测试性能时确保它不受延迟地运行--如果可能的话,不支持调试器。

票数 4
EN

Stack Overflow用户

发布于 2017-10-18 09:24:07

我终于找到了解决办法。

当我试图在SpongyCastle GitHub上创建一个问题时,我注意到有比1.54更新的版本.我没早点调查这件事真傻。

只是提醒一下,在我的主要项目中,它并没有马上起作用。加密/解密机制是库项目的一部分,然后包含在我的主项目中。请记住,也更新你的主要项目,否则它仍将是非常缓慢的。

所以这对我来说很管用

  • 将海绵城堡版本更改为1.56
  • compileSdkVersion更改为26
  • buildToolsVersion更改为26.0.2
  • targetSdkVersion更改为26

无论是图书馆项目还是主要项目。

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

https://stackoverflow.com/questions/46764508

复制
相关文章

相似问题

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