我使用Realm作为我的本地数据库,需要加密。我试图使用Android Keystore来存储一个SecretKey,它似乎将它存储在KeyStore中,但是当我尝试使用SecretKey.getEncoded()时,它总是返回null。这是代码:
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
Enumeration<String> aliases = keyStore.aliases();
while(aliases.hasMoreElements()) {
Log.v("KEY ALIAS",aliases.nextElement());
}
SecretKey keyStoreKey = (SecretKey) keyStore.getKey(ALIAS, null);
if(keyStoreKey == null) {
Log.v("NO KEY","USING NEW KEY");
KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(ALIAS,
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT);
KeyGenParameterSpec keySpec = builder
.setKeySize(512)
.setRandomizedEncryptionRequired(true)
.setUserAuthenticationRequired(true)
.setUserAuthenticationValidityDurationSeconds(5 * 60)
.build();
KeyGenerator kg = KeyGenerator.getInstance("HmacSHA1", "AndroidKeyStore");
kg.init(keySpec);
keyStoreKey = kg.generateKey();
keyStore.setEntry(ALIAS,
new KeyStore.SecretKeyEntry(keyStoreKey),
new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.build());
} else {
Log.v("GOT KEY","USING OLD KEY");
}
//THIS IS THE LINE THAT RETURNS NULL WHEN USING A KEY FROM KEYSTORE
byte[] key = keyStoreKey.getEncoded();
然后我将在领域中使用字节数组'key'。代码在首次启动时(在创建密钥时)工作正常但如果它在密钥库中找到它,则在获取密钥的字节时它只返回null。
答案 0 :(得分:2)
这是故意的。 Android KeyStore在保存后不会公开密钥材料,您只能要求KeyStore代表您执行操作。
一种解决方案是使用双层密钥。它的工作方式大致如下:
我们正在开展示范项目here(仍在进行中)。