在我的应用程序中,我们使用RSA密钥,该应用程序在首次启动时生成(使用Android密钥库)。由于未知原因,应用程序无法从某些设备上的密钥存储区检索密钥。我检查了日志,我找不到这个bug与特定操作系统版本或特定设备模型之间的关联。此外,我确信应用程序只在创建密钥后才尝试读取它。所以 - 我的问题是:据我所知,android密钥库应该是持久的。什么会导致这样的错误?
Bellow是相关的代码示例。
密钥生成:
try {
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", keyStore.getProvider());
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){
KeyGenParameterSpec spec;
spec = new KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT| KeyProperties.PURPOSE_SIGN| KeyProperties.PURPOSE_VERIFY)
.setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
.setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
.setKeySize(2048)
.build();
generator.initialize(spec);
} else {
Calendar start = new GregorianCalendar();
Calendar end = new GregorianCalendar();
end.add(Calendar.YEAR, 500);
KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context)
.setAlias(alias)
.setSubject(new X500Principal("CN="+ subject))
.setSerialNumber(BigInteger.valueOf(new Random().nextInt(Integer.MAX_VALUE)))
.setStartDate(start.getTime())
.setEndDate(end.getTime())
.setKeySize(2048)
.build();
generator.initialize(spec);
}
return generator.generateKeyPair();
} catch (Exception e) {
logger.warn("Failed to create private key in store", e);
return null;
}
密钥库本身使用以下代码初始化:
KeyStore androidKeyStore = KeyStore.getInstance("AndroidKeyStore");
androidKeyStore.load(null);
return androidKeyStore;
我们使用以下代码来检索密钥,错误是在某些设备上keystore返回null:
try {
Key key = keyStore.getKey(alias, null);
if (key == null){
logger.warn("Key not found in key store");
return null;
}
if (key instanceof PrivateKey) {
// Get certificate of public key
Certificate cert = keyStore.getCertificate(alias);
// Get public key
PublicKey publicKey = cert.getPublicKey();
// Return a key pair
return new KeyPair(publicKey, (PrivateKey) key);
} else {
logger.warn("Key found, but not from current type. type found: " + key.getClass().getSimpleName());
}
return null;
}catch (Exception e){
logger.warn("Failed to get private key in store", e);
return null;
}
谢谢, 奥马尔
答案 0 :(得分:1)
万一有人会遇到同样的问题: 我发现用于Android的Azure Active Directory库受到类似issue的影响,并且通过阅读我看到的与two issues链接的代码,这些代码与此问题类似,我们有另一个问题。因此,我计划使用基于p12文件的密钥库,存储在app私有存储中。
答案 1 :(得分:1)
您是否会在生成后立即丢失钥匙或一段时间后丢失钥匙?请查看此问题AndroidKeyStore getEntry is consistently failing after certain point,该问题链接到这篇精彩的文章:http://doridori.github.io/android-security-the-forgetful-keystore/
这个故事的寓意是,如果您使用AndroidKeyStore准备在某些情况下丢失您的密钥!