Java,Android密钥库-提供未加密的API密钥或密钥以进行加密

问题描述

由于我是Android的新手,所以我正在隐藏API密钥,并找到了要解决的Android密钥库。但是,当我看到有关如何使用Android Keystore的示例时,我不了解的一件事是如何提供未加密的原始密钥进行加密?如果我存储在代码中,那岂不是超过了使用Android Keystore的目的吗?

摘自有关存储机密的文章: https://medium.com/@ericfu/securely-storing-secrets-in-an-android-application-501f030ae5a3

  1. 在应用首次运行时生成随机密钥;
  2. 当您要存储机密时,请从KeyStore中检索密钥,使用它加密数据,然后将加密的数据存储在 首选项。
  3. 要读取机密时,请从“首选项”中读取加密的数据,从“密钥库”中获取密钥,然后使用该密钥进行解密 数据

第二点,它说用它加密数据。如何在不暴露给代码/应用程序的情况下提供数据? 抱歉,我对此表示歉意。

谢谢

解决方法

private static final String KEYSTORE_PROVIDER = "AndroidKeyStore";
private static final String AES_MODE = "AES/GCM/NoPadding";
private static final String KEY_ALIAS = "MyNiceKey";

加载默认的AndroidKeyStore:

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

在KeyStore中生成AES密钥,在android的最新版本中,它是硬件支持的密钥库;这意味着很难从中提取密钥的字节:

if (!keyStore.containsAlias(KEY_ALIAS)) {
    KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES,KEYSTORE_PROVIDER);
    keyGenerator.init(new KeyGenParameterSpec.Builder(KEY_ALIAS,KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
            .setBlockModes(KeyProperties.BLOCK_MODE_GCM)                   
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
            .setRandomizedEncryptionRequired(false) 
            .build());
    keyGenerator.generateKey();
}

无论如何,您都应该使用.setRandomizedEncryptionRequired(true)。没有必要设置错误的协议。否则,如果您只需要加密几个字节(您的API密钥),则可以创建一个非对称的公共/私有密钥,并使用RSA对其进行加密,这样您甚至不需要提供IV。

话虽如此,当您从KeyStore获取密钥时:

 public static SecretKey getKeyStoreSecretKeyEntry(final String entryAlias)
            throws GeneralSecurityException,IOException {
        return ((KeyStore.SecretKeyEntry) getKeyStore().getEntry(entryAlias,null)).getSecretKey();
    }

返回的SecretKey不包含密钥材料(密钥的实际字节),而仅包含其引用。因此,您可以在Cipher旁边自由使用它来加密和解密所需的内容。在任何情况下,如果您使用API​​密钥直接向您的服务发出http请求,API密钥都会被暴露出来。最好的方法是使用Google Firebase之类的服务器

P.s。 Google提供了一个非常简单的库,可为您节省时间和头痛: https://developer.android.com/jetpack/androidx/releases/security

https://developer.android.com/topic/security/data

结论:您在android Key Store中生成的密钥是用户的属性,应将其用于保护用户的私人数据。因此,使用用户密钥加密API密钥(这是开发人员的私有数据)不是一个好习惯。使用服务器来保护API密钥。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...