使用 API 18 及更高版本将密钥存储在 Android KeyStore 中

Storing a secret key in Android KeyStore using API 18 and Above

安全不是我的专业领域,但我有一个关于使用 API 18 及更高版本在 Android KeyStore 中存储密钥的问题。我使用以下代码尝试存储我的密钥:

KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);

KeyStore.SecretKeyEntry sKeyEntry = new KeyStore.SecretKeyEntry(ivKey);

ks.setEntry(ALIAS, sKeyEntry, null); // This is where the issue is

我知道 "null" 应该是我构建的 KeyProtection 参数,但这不适用于 API 18. 这个问题有解决方法吗?我一直难以找到有效的方法。

EDIT 我应该提到将其保留为 null 会引发错误:

java.security.KeyStoreException: Protection parameters must be specified when importing a symmetric key

AndroidKeyStore 在 API 级别 23 之前不支持密钥。要执行您想要执行的操作,您必须将目标设置为 23 或更高级别。

您可以使用 AndroidKeyStore 对 public/private 密钥对(例如 RSA)的支持来加密密钥 material,然后将其存储在本地文件中。当你想使用它时,你需要使用私钥来解密它,然后一旦你有了密钥 material 使用普通的 Java 加密 APIs (即不要' t 指定 "AndroidKeyStore") 对其进行密码运算。

要了解如何使用 AndroidKeyStore RSA 密钥对进行加密和解密,请查看 http://www.androidauthority.com/use-android-keystore-store-passwords-sensitive-information-623779/

但是,我认为从安全角度来看,这并没有真正实现任何目标。您想要实现哪些安全目标?

要使用 AndroidKeyStore 创建 RSA(Public/Private) 密钥,您可以使用以下方法。

获取密钥库

val keyStore = KeyStore.getInstance("AndroidKeyStore")
keyStore.load(null)

检查 KeyStore 是否包含我们的密钥

如果 KeyStore 不包含密钥,则创建密钥

    if (!keyStore.containsAlias(KEY_NAME)) {

        val keyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore")
        keyPairGenerator.initialize(
            KeyGenParameterSpec.Builder(
                KEY_NAME,
                KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
            )
                .setAlgorithmParameterSpec(RSAKeyGenParameterSpec(2048, F4))
                .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
                .build()
        )

        val keyPair = keyPairGenerator.generateKeyPair()
        val publicKey = keyPair.public
        val privateKey = keyPair.private
    }

使用 KEY_NAME

检索密钥
val privateKeyEntry = keyStore.getEntry(KEY_NAME, null) as KeyStore.PrivateKeyEntry
val privateKey = privateKeyEntry.privateKey
val publicKey = privateKeyEntry.certificate.publicKey

更多信息可以参考this: