You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Android KeyStore生成、保存并复用AES对称密钥?

解决方案:用Android KeyStore持久化AES密钥

嘿,我刚好踩过这个坑!你之前直接生成的AES密钥是存在内存里的,应用一重启自然就没了。要实现重启后能拿到同一个密钥,核心是把密钥安全存在Android KeyStore中——KeyStore会把密钥加密存在系统安全区域,只有你的应用能访问,而且重启设备都不会丢。

下面是具体的实现步骤,直接就能用:

1. 封装KeyStore工具类,搞定密钥的生成与获取

先写一个工具类,负责从KeyStore里捞已有的AES密钥,没有的话就生成新的存进去:

import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties
import java.security.KeyStore
import javax.crypto.KeyGenerator
import javax.crypto.SecretKey

class KeyStoreManager {
    // 给你的密钥起个唯一别名,别乱改,改了就找不到旧密钥了
    private val KEY_ALIAS = "my_app_secure_aes_key" 
    private val keyStore = KeyStore.getInstance("AndroidKeyStore").apply {
        load(null) // 初始化KeyStore
    }

    // 获取AES密钥:有就拿,没有就生成并存进KeyStore
    fun getAesKey(): SecretKey {
        // 先尝试从KeyStore取已有密钥
        val existingKey = keyStore.getKey(KEY_ALIAS, null) as? SecretKey
        existingKey?.let { return it }

        // 没有的话生成新密钥,配置好参数后存入KeyStore
        val keyGenerator = KeyGenerator.getInstance(
            KeyProperties.KEY_ALGORITHM_AES,
            "AndroidKeyStore"
        )
        val keySpec = KeyGenParameterSpec.Builder(
            KEY_ALIAS,
            // 密钥用途:加密+解密
            KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
        )
            .setBlockModes(KeyProperties.BLOCK_MODE_GCM) // 强推GCM模式,自带防篡改校验
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
            .setUserAuthenticationRequired(false) // 不需要生物验证就设false,要的话改成true
            .setKeySize(256) // AES-256,安全性拉满
            .build()

        keyGenerator.init(keySpec)
        return keyGenerator.generateKey()
    }
}

要是你用Java,逻辑完全一样,语法调整下就行:

import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import java.security.KeyStore;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

public class KeyStoreManager {
    private static final String KEY_ALIAS = "my_app_secure_aes_key";
    private final KeyStore keyStore;

    public KeyStoreManager() throws Exception {
        keyStore = KeyStore.getInstance("AndroidKeyStore");
        keyStore.load(null);
    }

    public SecretKey getAesKey() throws Exception {
        // 先取已有密钥
        SecretKey existingKey = (SecretKey) keyStore.getKey(KEY_ALIAS, null);
        if (existingKey != null) {
            return existingKey;
        }

        // 生成新密钥并存入KeyStore
        KeyGenerator keyGenerator = KeyGenerator.getInstance(
                KeyProperties.KEY_ALGORITHM_AES,
                "AndroidKeyStore"
        );
        KeyGenParameterSpec keySpec = new KeyGenParameterSpec.Builder(
                KEY_ALIAS,
                KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT
        )
                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                .setUserAuthenticationRequired(false)
                .setKeySize(256)
                .build();

        keyGenerator.init(keySpec);
        return keyGenerator.generateKey();
    }
}

2. 在加密逻辑里替换成这个密钥

以后再也不用自己临时生成AES密钥了,直接调用getAesKey()就行,和你之前的加解密逻辑无缝衔接:

// 示例加密代码
val keyStoreManager = KeyStoreManager()
val aesKey = keyStoreManager.getAesKey()

// 下面就是你原来的加解密逻辑,完全不用改
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipher.init(Cipher.ENCRYPT_MODE, aesKey)
// ... 剩下的加密操作该咋写咋写

3. 关于RAM存储的补充

如果有些场景你需要临时密钥,不想持久化,那可以用一个单例类把密钥存在内存里:

object TempKeyHolder {
    var tempAesKey: SecretKey? = null
}

但要注意,这种方式下应用一重启密钥就没了,只适合临时用的场景。你的核心需求是重启后能拿到同一个密钥,所以优先用Android KeyStore的方案。

几个关键提醒

  • 密钥别名KEY_ALIAS一定要固定死,别动态生成,不然每次都会创建新密钥,旧数据就解不开了
  • 一定要用GCM块模式,比ECB/CBC安全太多,还自带数据完整性校验,防止加密数据被篡改
  • 如果要更高的安全性,可以把setUserAuthenticationRequired(true)打开,这样只有用户验证指纹/密码后才能用密钥,但要注意适配不同Android版本的生物验证逻辑
  • KeyStore的密钥和你的应用签名绑定,只要签名不变,卸载重装后依然能拿到之前的密钥(Android 6.0+基本都支持)

这样弄完之后,不管你杀应用还是重启手机,调用getAesKey()都会拿到同一个AES密钥,之前加密的数据就能正常解密啦!

内容的提问来源于stack exchange,提问作者Alexandre Blanchet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:00:22