java-在SecretKey上调用.getEncoded()返回null

java-在SecretKey上调用.getEncoded()返回null,第1张

概述我使用以下代码生成AES密钥:KeyGenParameterSpec.Builderbuilder=newKeyGenParameterSpec.Builder("db_enc_key",KeyProperties.PURPOSE_ENCRYPT|KeyProperties.PURPOSE_DECRYPT);KeyGenParameterSpeckeySpec=builder.setKeySize(256)

我使用以下代码生成AES密钥:

KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder("db_enc_key", KeyPropertIEs.PURPOSE_ENCRYPT | KeyPropertIEs.PURPOSE_DECRYPT);        KeyGenParameterSpec keySpec = builder                .setKeySize(256)                .setBlockModes("CBC")                .setEncryptionpaddings("PKCS7padding")                .setRandomizedEncryptionrequired(true)                .setUserAuthenticationrequired(true)                .setUserAuthenticationValIDityDurationSeconds(5 * 60)                .build();        KeyGenerator keyGen = KeyGenerator.getInstance("AES", "AndroIDKeyStore");        keyGen.init(keySpec);        SecretKey sk = keyGen.generateKey();

但是每次我尝试通过sk.getEncoded()获取密钥的byte []版本时,该方法都会返回null.该文档说应该返回编码后的密钥,如果该密钥不支持编码,则返回null,但是我不认为该密钥不支持编码.

我需要byte [],因为我想加密一个领域数据库(为此我需要将2个AES-256密钥组合为字节数组)[https://realm.io/docs/java/latest/#encryption]

官方文档使用SecureRandom,但也指出这样做是一种愚蠢的方式,并且永远不会存储密钥.因此,我想使用KeyStore安全地存储两个单独的AES-256密钥.

附注:该代码仅是测试代码,而不是最终产品,因此对编码样式的任何评论都是无用的.我目前正试图获得一个工作版本.

编辑:因此,我尝试了以下代码,该代码成功生成了AES密钥(尽管只有16个字节的长度):

SecretKey sk1 = KeyGenerator.getInstance("AES").generateKey();

当我在其上使用getEncoded()方法时,我什至会得到字节数组,因此自然地我继续使用以下代码将其保存到KeyStore中:

KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(sk1);KeyStore.ProtectionParameter pp = new KeyProtection.Builder(KeyPropertIEs.PURPOSE_DECRYPT | KeyPropertIEs.PURPOSE_ENCRYPT).build();keyStore.setEntry("db_enc_key_test", entry, pp);

这也有效.因此,我尝试通过KeyStore.Entry entry2 = keyStore.getEntry(“ db_enc_key_test”,null);从密钥库中读取密钥.效果也不错.但是,当我调用entry2.getEncoded()时,该方法再次返回null.这是密钥库问题吗?

edit2:所以我才发现,在密钥库中生成的对称密钥(显然已经保存到该密钥)在AndroID M中是不可导出的,这似乎是故意的,这使我有点问题,因为我需要密钥本身加密领域数据库.

这里有一些领域开发人员推荐最佳实践吗?

解决方法:

无法检索编码的密钥是设计使然,因为密钥库应该是唯一知道它的密钥库.但是,您可以使用双层密钥:

1)生成一个随机密钥并将其存储在密钥库中.

2)生成Realm使用的“真实”密钥,并使用密钥库中的密钥对其进行加密.

3)现在您可以将一些完全随机的文本存储在例如SharedPreferences或磁盘上的文件中.

4)每当人们想要打开Realm时,请读取磁盘上的加密密钥,使用Keystore对其进行解密,现在您可以使用它来打开Realm.

此仓库使用相同的技术以安全的方式保存用户数据:https://github.com/realm/realm-android-user-store

这可能是您追求的课程:https://github.com/realm/realm-android-user-store/blob/master/app/src/main/java/io/realm/android/CipherClient.java它还通过各种AndroID版本处理回退(Keystore有很多怪癖).

总结

以上是内存溢出为你收集整理的java-在SecretKey上调用.getEncoded()返回null全部内容,希望文章能够帮你解决java-在SecretKey上调用.getEncoded()返回null所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1091330.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存