
[英]Android KeyStore to store the SecretKey for encryption/decryption
[英]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 unknown
该Operation 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.