FastAES:比SDK快10倍的AES加解密实现

一、序

之前了解AES加解密的过程中,阅读了一篇文章:《AES简介》

除了从这篇文章中学习了AES原理之外,还了解到有"查表"的实现,

于是下载从其文章链接的源码下来,在Android平台上试用了一下,确实比Android SDK自带的实现要快很多。

但是文章作者所实现的源码只有128bits版本,于是在github上联系了作者,然后被告知openssl上有完整的128bits和256bits的版本。

openssl的代码是C语言,Android平台使用的话需要封装一下。

其实之前已经实现了,集成在在 github.com/BillyWei01/... ,但没有发布到MavenCentral。

最近 FastKV 更新了,支持注入自定义加密,于是抽取出来单独发布了,并将其命名为FastAES(也懒得再想其他命名了)。

FastKV的加解密替换成FastAES之后,确实比之前的加解密快很多!

二、使用

2.1 导入

gradle 复制代码
dependencies {
    implementation 'io.github.billywei01:fastaes:1.1.2'
}

目前aar包只编译了 'armeabi-v7a', 'arm64-v8a' 两种abi架构。

如果需更多架构可以自行下载源码编译,或者联系我添加。

2.2 使用

java 复制代码
    byte[] cipher = FastAES.encrypt(data, key, iv);
    byte[] plain = FastAES.decrypt(cipher, key, iv);

以上接口实现的是 "AES/CBC/PKCS7Padding" 模式。

encrypt可能再内存不足时抛异常;

decrypt可能再内存不足,或者输入的密文非法时抛出异常。

使用时需酌情处理异常。

不过如果确实是内存不足,那其他地方可能也会抛OOM。

三、性能

测试数据:1000个长度在100字节以内的随机数组。

测试设备:HUAWEI P30 Pro。

测试结果:

耗时(ms)
FastAES 1
SDK AES 24
KeyStore AES 20036

和Android SDK的AES实现对比,要快一个数量级。

文章标题说的快10倍,说的是大概的量级,对于不同长度输入,差距有所浮动。

如果随机数组长度更长一些,差距会稍微缩小,但是还是差一个数量级。

关于为什么SDK提供的AES不如openssl的查表实现,我也不清楚。

推测是SDK的AES需要根据字面量 "AES/CBC/PKCS7Padding" 去找算法提供方(Provider), 路由过程包括检索和对象创建等,这方面耗费不少;

然后就是openssl的查表实现确实比SDK的AES核心实现确实要快一些?

需要指出的是,查表的实现,需要一个10K左右的表;

对于目前的手机设备来说,10K的空间应该还好。

四、KeyStore加密

这一小节是题外话,但也值得讲一讲。

从上面列出的测试结果来看,用KeyStore做AES加解密,速度究极慢。

可能是因为加密过程要在TTE上执行的缘故?

这方面我也不太清楚,有了解的朋友可以和大家分享一下。

但不管什么原因,KeyStore确实不适合用来加密大量数据。

一种折中的方式是通过KeyStore来生成密钥。

java 复制代码
public class KeyStoreHelper {
    private static final String ALIAS = "KeyStoreHelper";

    public static byte[] getKey(byte[] seed) {
        try {
            String algorithm = KeyProperties.KEY_ALGORITHM_HMAC_SHA256;
            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
            keyStore.load(null);
            Key key = keyStore.getKey(ALIAS, null);
            if (key== null) {
                // Generate the key and save to KeyStore, next time we can get it from KeyStore.
                KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm, "AndroidKeyStore");
                keyGenerator.init(new KeyGenParameterSpec.Builder(ALIAS, KeyProperties.PURPOSE_SIGN).build());
                key = keyGenerator.generateKey();
            }
            Mac mac = Mac.getInstance(algorithm);
            mac.init(key);
            byte[] digest = mac.doFinal(seed);
            return Arrays.copyOf(digest, 16);
        } catch (Exception e) {
            FastKVLogger.INSTANCE.e("Cipher", e);
        }
        return new byte[16];
    }
}

KeyGenParameterSpec 是Android M (Android 6.0) 提供的API,

用其构建的随机的Key会保存在KeyStore中,在下次启动时, keyStore.getKey能获取到其生成的Key。

如上的实现,输入seed,会得到随机的byte\[\] (可以作为AES的key);

下次启动输入相同的seed, 会得到相同的输出。

也就是,可用 KeyStore对固定的seed计算HMAC(或者AES也行),用其计算结果作为AES的key,再选一个更快的AES实现来加密。

如此,既利用了KeyStore的保密性,又避免了直接利用其加密的效率问题。

需要注意的是,KeyStore保存的Key会在APP卸载时一并删除;

卸载重装后,用同样的ALIAS获取到的Key会不一样。

也就是,KeyStore的Key,可以用来加密生命周期在安装期间的数据(比如内部目录的数据),不可以用来加密生命周期更长的数据(比如云端的数据),否则卸载重装后解密不了。

五、总结

通过封装openssl的AES查表实现,得到了一个比Android SDK提供的加密更快的实现。

对于需要频繁加解密,且对速度有一定要求的场景,可以用之改善。

项目已上传Github: github.com/BillyWei01/...

欢迎各位朋友点赞、收藏、投star !

相关推荐
apple_6926588532 分钟前
一个开源 KTV 点歌项目电视大屏点歌系统,免激活码家庭K歌方案
开源·音视频
承渊政道1 小时前
【从零开始大模型开发与微调:基于PyTorch与ChatGLM】(从ChatGLM本地化到LoRA、PEFT的高级微调)
android·人工智能·pytorch·chatglm·本地化部署·大模型开发与微调
鶴哥只手遮天1 小时前
React 19.3.1 源码深度剖析-第 12 章(下)RSC 与 Flight 协议
前端·react.js·开源
Ikalus19882 小时前
gogs 公告说修好了,7 天后有人说还在
开源
badhope2 小时前
我用MonkeyCode搭了一个照片筛选器,然后发现本地IDE真的不香了
开源
TTATTC2 小时前
让 16 个 AI 员工在飞书群自我协同:基于 OpenClaw 的多 Agent 敏捷 Squad 拓扑与一人公司实操
docker·开源
TTATTC2 小时前
从分片续传到 SPI 插件化扩展:Free-FS 企业级文件系统核心架构与万能预览技术拆解
docker·开源
doujiaozh2 小时前
从 0 到 1:我用 300 行代码给 AI 记忆加上了“不可篡改的收据”(附开源实现)
人工智能·开源
十方空烬2 小时前
开源雷达 · 2026-10-18:模型不再是主角,agent 的操作层才是
开源
2601_962885723 小时前
如何用 Python 判断一只股票“追涨”还是“抄底”更有效?
android·开发语言·python