我正在使用KeyStore将我的应用程序秘密安全地存储在安卓系统中。然而,我发现对于带有Android7.1.1及更低版本的设备,使用KeyStore存储的密钥不是“硬件支持的?”,也就是说,每当我将isInsideSecureHardware()方法调用到KeyInfo时,它总是会返回'false‘。
据我测试,即使设备在设置->Security->凭证存储->存储类型中具有“Storage type =Hardware”,也会发生这种情况。但是,Android7.1.2和更高版本的情况并非如此,只要凭据存储类型是硬件支持的,它总是为isInsideSecureHardware()返回“true”;从未尝试过其他类型。
下面是我的代码片段,用于注入密钥并检查KeyInfo (是的,我请求安卓4.3...please忽略代码中的版本检查):
private void injectKey(Context context, String keyName){
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
Calendar start = Calendar.getInstance();
Calendar end = Calendar.getInstance();
end.add(Calendar.YEAR, 1);
keyGenerator.init(new KeyGenParameterSpec.Builder(keyName, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.setRandomizedEncryptionRequired(true)
.setKeyValidityStart(start.getTime())
.setKeyValidityEnd(end.getTime())
//.setUserAuthenticationRequired(true) //need PIN to get key
//.setUserAuthenticationValidityDurationSeconds(86400) //1-day time can use key from entering PIN
//.setUnlockedDeviceRequired(true) API level 28
//.setIsStrongBoxBacked(true) API level 28
.build()
);
}
SecretKey secretKey = keyGenerator.generateKey();
//check key info
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
SecretKeyFactory factory = SecretKeyFactory.getInstance(secretKey.getAlgorithm(), "AndroidKeyStore");
KeyInfo keyInfo;
try {
keyInfo = (KeyInfo) factory.getKeySpec(secretKey, KeyInfo.class);
boolean insideHW = keyInfo.isInsideSecureHardware();
boolean authReq = keyInfo.isUserAuthenticationRequired();
boolean authHW = keyInfo.isUserAuthenticationRequirementEnforcedBySecureHardware();
String[] blockModes = keyInfo.getBlockModes();
String[] digests = keyInfo.getDigests();
String[] encryptionPaddings = keyInfo.getEncryptionPaddings();
int keySize = keyInfo.getKeySize();
Date keyValidityStart = keyInfo.getKeyValidityStart();
Date keyEndValid = keyInfo.getKeyValidityForConsumptionEnd();
String keyAlias = keyInfo.getKeystoreAlias();
int keyPurpose = keyInfo.getPurposes();
String [] signaturePaddings = keyInfo.getSignaturePaddings();
int authType = keyInfo.getUserAuthenticationValidityDurationSeconds();
MainActivity.showMessage(context, "Key Info",
"inside HW = " + insideHW + "\n" +
"auth Req = " + authReq + "\n" +
"auth HW = " + authHW + "\n" +
"keySize = " + keySize + "\n" +
"keyValidityStart = " + keyValidityStart + "\n" +
"keyEndValid = " + keyEndValid + "\n" +
"keyAlias = " + keyAlias + "\n" +
"keyPurpose = " + keyPurpose + "\n" +
"authType = " + authType + "\n");
String checkKeyInfo = "";
} catch (InvalidKeySpecException e) {
String checkKeyInfo = "";
}
}
}
发布于 2021-01-29 20:16:41
虽然Android硬件密钥库只支持从API 23开始存储AES密钥,但是版本与您的发现并不完全一致--您可能会更成功地使用RSA密钥,因为这些密钥是从API 18开始支持的。
链接到developer.android.com上的相关文档
这就是为什么因特网上存在“如何使用硬件密钥存储库加密”的例子,建议在密钥存储库中创建RSA密钥,使用SecureRandom或类似的方法创建256位AES密钥,然后使用私密的RSA密钥加密AES密钥,并将结果存储在SharedPreferences中。这可以在API 18+上工作,而不需要更改。
因此,尝试使用RSA密钥,您将有更多的运气,但仍然没有前API 18。
https://stackoverflow.com/questions/62425689
复制相似问题