- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我使用以下代码生成 AES key :
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() 获取 key 的 byte[] 版本时,该方法都会返回 null。文档说它应该返回编码后的 key ,如果 key 不支持编码,则返回 null,但我认为 key 不支持编码。
我需要 byte[] 因为我想加密一个 Realm 数据库(为此我需要将 2 个 AES-256 key 组合为字节数组)[ https://realm.io/docs/java/latest/#encryption]
官方文档使用 SecureRandom,但也指出这是一种愚蠢的做法,而且 key 永远不会被存储。因此,我想使用 KeyStore 来安全地存储两个单独的 AES-256 key 。
P.S.:代码只是测试代码,不是最终产品,所以对编码风格的任何评论都是无用的。我目前只是想让一个工作版本继续运行。
编辑:所以我尝试了下面的代码,它成功地生成了一个 AES key (虽然只有 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);
从 keystore 中读取 key ,效果也很好。但是当我调用 entry2.getEncoded()
时,该方法再次返回 null。这是 keystore 问题吗?
edit2:所以我刚刚发现,在 keystore 中生成(并显然保存到)的对称 key 在 Android M 中是不可导出的,这似乎是有意为之的,这让我遇到了一些问题,因为我需要 key 本身来加密 Realm 数据库。
这里有一些 Realm 开发人员推荐最佳实践吗?
最佳答案
您无法检索编码 key 这一事实是设计使然,因为 keystore 应该是唯一知道它的人。但是,您可以使用双层 key :
生成一个随 secret 钥并将其存储在 keystore 中。
生成 Realm 使用的“真实” key ,并使用 keystore 中的 key 对其进行加密。
现在您有一些完全随机的文本,可以存储在例如 SharedPreferences 或磁盘文件中。
每当人们想要打开 Realm 时,读取磁盘上的加密 key ,使用 Keystore 对其进行解密,现在您就可以使用它来打开 Realm。
这里的这个 repo 使用相同的技术以安全的方式保存用户数据:https://github.com/realm/realm-android-user-store
这可能是您要学习的类(class):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,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42348944/
我使用以下代码将 key 转换为字节 SecretKey key = KeyGenerator.getInstance("DES").generateKey(); byte[] bkey=key.ge
我需要在 Java 中生成一个随机的 SecretKey,我将能够在未来的某个时候重新生成它。这个想法是这个 key 对于创建它的机器是唯一的并且不存储在任何地方。我正在尝试这样的事情: KeyGen
我希望能够将 DES SecretKey 保存到文件中,以便您稍后可以导入和使用它。看了好几条路线,好像都有些啰嗦,有没有简洁明了的方法呢? 最佳答案 在 Java 中将 SecretKey 保存到文
我想把String转成secretKey public void generateCode(String keyStr){ KeyGenerator kgen = KeyGenerator.getIn
我遇到了一个问题,当用户向他们的 Android 设备添加新指纹时,我想使 SecretKey 无效。我可以生成 key ,毫无问题地拉出生物识别提示。当我添加新指纹时, key 不会引发异常..它仍
我正在尝试将 key 保存在 XML 文件中,以便稍后解密加密字符串,该软件可以在“Encrypt()”方法中加密并返回我,但在尝试使用“Decrypt( )”方法 代码 private stati
我目前使用 DES 作为加密/解密数据的实践方法(我知道这不是行业惯例!)并且我在解密时遇到错误(这里是输出): java.security.InvalidKeyException: Paramete
我试图用我的公钥加密一个secretKey,然后用私钥在其他地方解密它。我可以很好地加密和解密,但是当我这样做时,我得到了一个完全不同的 key 。 这是创建公钥/私钥对的代码 public stat
我试图简单地加密一些文本,将其保存在文本文件中,然后加载/解密它。 使用Java网站上的教程,我一直使用的代码: public class MainClass { public static vo
我正在编写一个函数,使用 SecretKeyFactory 根据密码生成 key (字节)。我想在不再需要时销毁 SecretKey 实例,但它会引发异常。 try { byte[] salt
我正在尝试在应用程序中的任何地方拥有 secret (字符串),保存为!所以我想出了这个想法,使用keyStore来存储 key ,只用它来加密和解密我的 secret 。以下是我如何保存(加密)我的
在EC2上运行时,accesskey和secret key可以通过curl命令获取 curl http://169.254.169.254/latest/meta-data/iam/security-
我想问你,将 LinkedIn ConsumerKey 和 ConsumerSecret 像常量一样保存在我的代码中是否安全? 如果不安全,使用 LinkedIn 进行身份验证的正确方法是什么? 最佳
我执行以下操作来根据 KeyStore 中的用户密码存储 SecretKey: // load KeyStore static byte[] salt = // for learning purpos
作为加密和保存数据的一部分,我们使用 AES 算法和 openssl 生成了 key 。 openssl enc -aes-256-cbc -P -nosalt Openssl 已生成 KEY 和 I
我正在尝试在 C# 应用程序中复制 Java 库中的加密逻辑。 Java 包含两种方法,我已设法在 C# 中复制它们。对于任何数据集,我在每个程序中都得到相同的结果。 createKey(byte d
我最近开始在设备中看到此错误。 java.security.InvalidKeyException: Only SecretKey is supported at com.androi
我目前正在研究 Java 中的 key 处理类,特别是使用 KeyStore。我正在尝试使用 AES 实例生成一个 SecretKey,然后使用 setEntry() 方法将它放在 KeyStore
我有一个使用 S3 存储桶的 Spring Boot 应用程序。根据亚马逊(https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/ja
我目前正在 Java 中开发一个 key 处理类,特别是使用 KeyStore。我正在尝试使用 AES 实例生成 SecretKey,然后使用 setEntry() 方法将其放入 KeyStore 中
我是一名优秀的程序员,十分优秀!