2014-09-22 85 views
6

我目前正在开发基于客户端 - 服务器体系结构的android应用程序。为了数据安全,我使用公私密钥对进行数据加密和签名。我正在使用AndroidKeyStore存储密钥对。下面是生成密钥对的代码:AndroidKeyStore在设备密码更改后消失

KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(
     mContext) 
     .setAlias(mPrivateKeyAlias) 
     .setSubject(new X500Principal("CN=" + mPrivateKeyAlias)) 
     .setSerialNumber(
       BigInteger.valueOf(System.currentTimeMillis())) 
     .setStartDate(start.getTime()) 
     .setEndDate(end.getTime()).setKeySize(2048).build(); 

KeyPairGenerator kpGenerator = KeyPairGenerator.getInstance(
     "RSA", 
     "AndroidKeyStore"); 

kpGenerator.initialize(spec); 
// Key Pair will be saved in AndroidKeyStore 
KeyPair pair = kpGenerator.generateKeyPair(); 

执行该代码后,密钥库相关型号文件(CERT和PKEY文件)将在“/数据/杂项/密钥库/ USER_0 /”目录下生成。 出于安全原因,我正在对应用敏感数据(如auth令牌)进行加密并将其保存到Shared Pref。

但是,现在当用户更改设备密码或PIN时,由于用于密钥存储加密的主密钥是使用设备凭证生成的,密钥存储文件正在被删除。

现在要解决这个问题,我试图将公私密钥对保存在RAM中以及密码被更改时。从onPasswordChanged(上下文的背景下,意图意图)DeviceAdminReceiver的方法,我在执行下面的代码:

KeyStore keyStore = KeyStore 
     .getInstance("AndroidKeyStore"); 
keyStore.load(null); 
keyStore.setKeyEntry(mPrivateKeyAlias, mPrivateKey.getPrivateKey(), 
     null, new Certificate[] { mPrivateKey.getCertificate() }); 

但是,这个代码后仅CERT文件被在'/data/misc/keystore/user_0/'目录中创建并同时使用解密私钥,给一些无效的签名错误。

此外,我已与服务器共享我的公钥,使用私钥加密数据,因此创建新的密钥对并不是更好的解决方案。

那么,如何在设备密码更改后保留我的公用密钥对?如果没有解决方法,AndroidKeyStore的确切用途是什么?我可以在哪里使用它?

+0

嘿,我刚刚写了一篇关于这个东西的文章http://systemdotrun.blogspot.co.uk/2015/02/android-security-forgetful-keystore.html – Dori 2015-02-27 15:05:35

+1

@ Dori的链接已经死了,这里是更新url http://doridori.github.io/android-security-the-forgetful-keystore/#sthash.dBNZUIC0.dpbs – Tom 2016-05-17 23:11:42

+0

Thx :)我现在正在为'KeyStore'写一个快速概览https:// github的.com/doridori/Android的安全 - 参考/斑点/主/ API/keystore.md – Dori 2016-05-19 08:09:43

回答

4

此问题已由Google在Android 5.0(Lollipop)版本中修复。但是,对于以前的Android版本,您将不得不忍受这个问题。 :(