使用存储在KeyStore中的密钥加密Realm

时间:2016-04-08 17:08:00

标签: android encryption realm

我正在尝试在我的应用中设置加密的默认域实例。 我们的想法是使用带有给定别名的 KeyPairGenerator 生成密钥,将其存储在 AndroidKeyStore 中,并在每次需要时使用所述密钥。

我做什么

这是我生成密钥的方式:

  KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
        ks.load(null);

        if (!ks.containsAlias(KEY_ALIAS)) {

            Calendar start = Calendar.getInstance();
            Calendar end = Calendar.getInstance();
            end.add(Calendar.YEAR, 99);

            KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(this)
                    .setAlias(KEY_ALIAS)
                    .setSubject(new X500Principal("CN=Example, O=ExampleOrg"))
                    .setSerialNumber(BigInteger.ONE)
                    .setStartDate(start.getTime())
                    .setEndDate(end.getTime())
                    .build();

            KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
            generator.initialize(spec);

            KeyPair keyPair = generator.generateKeyPair();
        }

我正在使用 KeyPairGenerator ,因为我需要支持api版本18及更高版本。

以下是我在应用程序中设置默认域实例的方法:

 RealmConfiguration config = null;
    try {
        config = new RealmConfiguration
                .Builder(this)
                .encryptionKey(ks.getKey(KEY_ALIAS, null).getEncoded())
                .name("dealmatrix.realm")
                .schemaVersion(1)
                .build();

其中ks是如此获取的Keystore实例:

Keystore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);

什么错误

我的问题是这个表达式:

ks.getKey(KEY_ALIAS, null).getEncoded()

返回null,这可以理解地导致异常。

我在网上看到这是KeyStore系统的预期行为。

如果我确实无法获取存储的加密密钥的字节数组,我应该如何使用所述密钥加密我的领域?

是否有其他方法可以安全地存储加密密钥,以便我可以在我的领域配置中使用它?

2 个答案:

答案 0 :(得分:1)

在Realm存储库的feature/example/store_password分支中有一个WIP示例项目,它使用Android密钥库。

https://github.com/realm/realm-java/tree/feature/example/store_password/examples/StoreEncryptionPassword

核心逻辑用Store.java

编写

在发布此示例项目之前,我们还需要更多工作(清理,添加注释,支持旧设备)。但我认为这个项目可以帮助你。

答案 1 :(得分:0)

Android Keystore禁止从中提取私钥。因此,设计将是在Android Keystore之外生成Realm密钥,以便您可以将其用于Realm数据库的加密/解密。

但是要安全存储该Realm密钥,您可以使用Android Keystore的功能,方法是使用Android Keystore加密Realm密钥,然后将其存储在本地(例如,共享首选项)。稍后,您可以读取该加密的Realm密钥,使用Android Keystore对其进行解密,然后再次使用它来解锁Realm数据库。