我正在使用 AndroidKeyStore 生成 RSA 密钥对,用于加密/解密内部数据。
执行此操作的代码如下 - 它尝试检索现有的 RSA 密钥对(通过别名)。如果不存在,那么它会尝试生成一个新的。
代码如下 -
private void initializePublicPrivateKeys(){
try
{
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(APP_RSA_KEY_PAIR_SECRET_ALIAS, null);
_app_privateRSAKey = entry.getPrivateKey();
_app_publicRSAKey = entry.getCertificate().getPublicKey();
}
catch(Exception e){
}
}
private void initializeRSAKeyPairs() {
initializePublicPrivateKeys();
boolean isKeyNotGenerated = _app_privateRSAKey == null || _app_publicRSAKey == null;
if(isKeyNotGenerated)
{
//Check here, if we already stored some data with previous RSA key pair - if a entry is present in SharedPreference then that would mean we had previously generated a RSA key pair and the entry is in-turn encrypted by this key pair.
generateAppRSAPublicPrivateKeys();
initializePublicPrivateKeys();// initialize it again , since we have new keys generated.
}
}
@TargetApi(18)
private void generateAppRSAPublicPrivateKeys(){
Calendar cal = Calendar.getInstance();
Date now = cal.getTime();
// the certificate created would be valid for 25 years. This is just a random value.
cal.add(Calendar.YEAR, 25);
Date end = cal.getTime();
try{
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
Context appContext = getApplicationContext();
KeyPairGeneratorSpec.Builder keyPairGeneratorBuilder =
new KeyPairGeneratorSpec.Builder(appContext)
.setAlias("myrsaalias")
.setStartDate(now)
.setEndDate(end)
.setSerialNumber(BigInteger.valueOf(1))
.setSubject(new X500Principal(String.format("CN=%s, OU=%s", "myrsaalias",
appContext.getApplicationInfo().packageName)));
if(Build.VERSION.SDK_INT >= 19){
keyPairGeneratorBuilder.setKeySize(2048);
}
generator.initialize(keyPairGeneratorBuilder.build());
generator.generateKeyPair();
}
catch(Exception e){
e.printStackTrace();
throw new IllegalArgumentException("Failed to generate RSA Public Private Key pair");
}
}
这段代码工作正常。生成密钥对后,我使用它们来加密/解密数据(将此数据存储在共享首选项中),但是在某个时间点(在某些应用程序重新启动后)之后,initializePublicPrivateKeys 函数无法检索密钥对。(在这一点之后持续失败)
因此,以加密形式存储在共享首选项中的任何数据都会丢失,因为我根本没有相应的公钥来解密它。 (如果我生成一个新的,我想,这会有所不同,并且当我解密数据时会返回错误的结果)
我想知道在什么情况下这个初始化公钥函数会失败?
PS:目前,我无法捕获异常详细信息,因为问题发生在我无权访问的某些客户设备上,我需要自己找出问题的根源。
此外,在此期间设备密码或 PIN 码不会更改(我与客户确认了这一点)
提前致谢,
用户是否有可能将屏幕锁定类型更改为不安全的方法(例如 None 或 Swipe),从而触发 AndroidKeyStore 中的所有密钥被删除?也许用户在设置中添加或删除了指纹?中的密钥无效AndroidKeyStore
是本博客文章中讨论的已知问题(功能):https://doridori.github.io/android-security-the-forgetful-keystore/
这里还提到:https://code.google.com/p/android/issues/detail?id=61989
如果您没有严格的安全要求,并且希望您的应用程序即使用户没有屏幕锁定也能工作,那么也许只需使用存储在数据区域的密钥库文件中的密钥对并跳过AndroidKeyStore
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)