我想将我的AES-256密钥存储到AndroidKeyStore,此AES-256密钥是原始密钥(随机的32个字节)。我尝试这样的代码。
public foo () {
SecureRandom sr = new SecureRandom();
byte[] key = new byte[32];
sr.nextBytes(key);
try {
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
SecretKeySpec sks = new SecretKeySpec(key, "AES");
SecretKeyFactory skf = SecretKeyFactory.getInstance("AES");
SecretKey sk = skf.generateSecret(sks);
ks.setEntry("key", new KeyStore.SecretKeyEntry(sk), new
KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT).build());
KeyStore.SecretKeyEntry entry = (KeyStore.SecretKeyEntry) ks.getEntry("key", null);
SecretKey skLoad = (SecretKey) ks.getKey("key", null);
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, skLoad);
Log.i(TAG, Arrays.toString(cipher.doFinal(plainBytes)));
} catch (Exception e) {
e.printStackTrace();
}
}
我在SecretKey行sk = skf.generateSecret(sks);处得到异常
java.security.spec.InvalidKeySpecException: To generate secret key in Android Keystore, use KeyGenerator initialized with android.security.keystore.KeyGenParameterSpec
我知道我们可以通过将KeyGenerator与KeyGenParameterSpec一起使用来保存密钥,但是我有一些使用所有者密钥的原因,而KeyGenParameter似乎无法导入我的所有者密钥。所以对这个问题有任何想法,谢谢大家!
答案 0 :(得分:2)
通常,您不应从密钥库外部导入密钥,因为它们在输入之前是不安全的。因此,以后添加它们的好处有限。
但是,您可以做一些技巧:在密钥存储区中创建一个包装密钥,并使用它来包装对称密钥并存储结果。然后,您可以在再次需要该密钥时简单地撤消该过程。
不幸的是,通常没有实现存储密钥的最佳方法,例如(GCM-)SIV模式,但是,嘿,现在您至少听说过它。