繁体   English   中英

Android:将SecretKey存储在KeyStore中

[英]Android: Store SecretKey in KeyStore

我使用SecretKey加密应用程序中的敏感数据。 目前,我正在以DB64或SharedPrefs的Base64编码格式存储我的SecretKey,这不是在根电话上存储Secret的安全位置。 因此,我想将SecretKey移至Android KeyStore 我面临的问题是,当我尝试从Google获得此示例代码时,它期望使用PrivateKey而不是SecretKey。 我想不出一种方法来将我的SecretKey存储在KeyStore中并获取它以供以后使用。 我尝试了这个:

private static void writeSecretKeyToKeystore(SecretKey secretKey, Context context) {
KeyStore keyStore = null;
try {
  keyStore = KeyStore.getInstance("AndroidKeyStore");
  keyStore.load(null);
  KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(secretKey);
  keyStore.setKeyEntry("Key", secretKeyEntry.getSecretKey().getEncoded(), null);
} catch (KeyStoreException e) {
  e.printStackTrace();
} catch (CertificateException e) {
  e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
  e.printStackTrace();
} catch (IOException e) {
  e.printStackTrace();
}

当我尝试上述代码时,它将引发异常, Operation not supported because encoding is unknown ,因此Operation not supported because encoding is unknownOperation not supported because encoding is unknown

任何示例代码都会有很大帮助。

错误
java.security.KeyStore可以存储对称密钥和非对称密钥。 您只需要实例化KeyStore.SecretKeyEntry并将其传递给构造函数中的SecretKey,然后使用KeyStore#setEntry方法进行保存:

keyStore.setEntry(
     "key1",
     new KeyStore.SecretKeyEntry(secretKey),
     new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
             .setBlockMode(KeyProperties.BLOCK_MODE_GCM)
             .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
             .build());

要使其退回,请使用:

SecretKey keyStoreKey = (SecretKey) keyStore.getKey("key1", null);

更新
经过一番研究,我惊讶地发现AndroidKeyStore不支持对称密钥。 (请参见讨论: https : //groups.google.com/forum/#!topic/android- developers/ gbmIRKRbfq8

解决方法是加密您的SecretKey并将其存储在SharedPreferences中。 然后将密钥存储以在密钥库中解密您的密钥。 这是使用scytale的实现。

public static String getBase64EncodedSecretKey(){
    Store store = new Store(context);
    Crypto crypto = new Crypto(Options.TRANSFORMATION_SYMMETRIC);
    SecretKey key = store.getSymmetricKey("key_alias", null);
    String encryptedData = PreferenceManager.getDefaultSharedPreferences(context).getString("myEncryptedSecretKey", "");
    return crypto.decrypt(encryptedData, key);
}

public static void storeKey(String base64EncodedSecretKey){
    Store store = new Store(context);
    if (store.hasKey("key_alias")) {
        store.deleteKey("key_alias");
    }
    SecretKey key = store.generateSymmetricKey("key_alias", null);
    Crypto crypto = new Crypto(Options.TRANSFORMATION_SYMMETRIC);
    String encryptedData = crypto.encrypt(base64EncodedSecretKey, key);
    PreferenceManager.getDefaultSharedPreferences(context).edit().putString("myEncryptedSecretKey",encryptedData).apply();
}

// Usage:
//store SecretKey
byte[] encodedKey = secretKeyEntry.getSecretKey().getEncoded();
String base64EncodedKey = Base64.encodeToString(encodedKey);
storeKey(base64EncodedKey);

//get SecretKey
String base64EncodedKey = getBase64EncodedSecretKey();
byte[] encodedKey = Base64.decode(base64EncodedKey);
SecretKey originalKey = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM