使用存储在KeyStore中的密钥加密领域

使用存储在KeyStore中的密钥加密领域

问题描述:

我想在我的应用程序中设置一个加密的默认领域实例。 这个想法是使用具有给定别名的KeyPairGenerator生成密钥,将其存储在AndroidKeyStore中,并在每次需要时使用所述密钥。使用存储在KeyStore中的密钥加密领域

我做什么

我这是怎么生成密钥:

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 ks = KeyStore.getInstance("AndroidKeyStore"); 
ks.load(null); 

什么不顺心

我的问题是这个表达式:

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

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

我在线阅读,这是KeyStore系统的预期行为。

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

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

+0

你是否想出了任何解决方案,我也面临这个问题 – saikrupa

从getEncoded返回null的Android Keystore键按预期工作。 getEncoded应该返回私钥的密钥材料(通常采用PKCS#8 DER编码格式),如果不支持密钥材料导出,则返回null。 Android Keystore按设计不会显示/导出私钥或秘密密钥的密钥材料,因此getEncoded将返回null。请参阅https://developer.android.com/training/articles/keystore.html#SecurityFeatures

您仍然可以在Signature和Cipher抽象中使用这些密钥。

+0

好吧,我明白了。你说什么是有道理的,但这并不能真正回答我的问题。我如何安全地为我的Realm配置存储加密密钥呢? – Rakatan

+0

什么是领域?通常,您可以使用您使用Key实例初始化的Cipher原语来加密内容。在这种情况下,您可以从Android Keystore获取Key实例。 –

+0

https://realm.io/。这是一个数据库。我知道Keystore是如何工作的,但数据库的加密方法只接受一个字节数组。 – Rakatan

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

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

核心逻辑是写在Store.java

我们需要一些更多的作品(清理,添加评论,支持老设备)释放这个例子项目之前。但我认为这个项目可以帮助你。