在 Android 的密钥库中存储私钥

Posted

技术标签:

【中文标题】在 Android 的密钥库中存储私钥【英文标题】:Storing private keys in keystore in Android 【发布时间】:2017-04-26 14:25:58 【问题描述】:

我需要在 SharedPreferences 中存储一些私人用户的值。

我看到了这篇文章: https://medium.com/@ericfu/securely-storing-secrets-in-an-android-application-501f030ae5a3

它解释了您必须做的大部分事情,但似乎缺少有关如何将私钥和公钥(用于 API

因此,如果我们有 API 版本 18-22,我们将执行以下操作: 我们打开一个密钥库

KeyStore keyStore = KeyStore.getInstance(AndroidKeyStore);
keyStore.load(null);

我们生成密钥对

Calendar start = Calendar.getInstance();
Calendar end = Calendar.getInstance();
end.add(Calendar.YEAR, 30);

KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(mContext)
                                .setAlias(KEY_ALIAS)
                                .setSubject(new X500Principal("CN=" + KEY_ALIAS))
                                .setSerialNumber(BigInteger.TEN)
                                .setStartDate(start.getTime())
                                .setEndDate(end.getTime())
                                .build();
KeyPairGenerator kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, AndroidKeyStore);
kpg.initialize(spec);
mEncryptionPair = kpg.generateKeyPair();

现在我们可以使用公钥加密数据,使用私钥解密。但是我们需要将密钥对保存到密钥库中,然后再检索它。 我该怎么做?

我也很关心为什么 Android Studio 会针对这一行显示警告

KeyPairGenerator kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, AndroidKeyStore);

警告:

Field requires API level 23 (current min is 14): android.security.keystore.KeyProperties#KEY_ALGORITHM_RSA

【问题讨论】:

【参考方案1】:

我知道,这个问题太老了,但我遇到了同样的问题。如果有人需要,这是解决方案

     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) 
                  spec = new KeyPairGeneratorSpec.Builder(mContext)
                        .setAlias(alias)
                        .setSubject(new X500Principal("CN=" + alias))
                        .setSerialNumber(BigInteger.valueOf(1337))
                        .setStartDate(start.getTime())
                        .setEndDate(end.getTime())
                        .build();
             else 
                spec = new KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_SIGN)
                        .setCertificateSubject(new X500Principal("CN=" + alias))
                        .setDigests(KeyProperties.DIGEST_SHA256)
                        .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
                        .setCertificateSerialNumber(BigInteger.valueOf(1337))
                        .setCertificateNotBefore(start.getTime())
                        .setCertificateNotAfter(end.getTime())
                        .build();
            

【讨论】:

以上是关于在 Android 的密钥库中存储私钥的主要内容,如果未能解决你的问题,请参考以下文章

Android 硬件支持的密钥库中的 PublicKey 有多安全?

检索私钥时链为空

libsodium PHP将私钥存储在文件中

为什么以太网密钥库密文 以十六进制字符串格式存储,长度仅为64?

存储 RSA 私钥 Android

无声安装PFX到Android系统可信CA用户密钥库