我希望使用Android硬件支持的KeyStore,但我担心安全性和可用性。 从我读过here开始,当用户更改设备锁时,KeyStore会被擦除,除非省略了setEncryptionRequired()。为了实用起见,似乎需要这样做,否则一旦设备锁被修改,所有硬件支持的密钥都会被擦掉。
但是,我还读过here硬件支持的密钥实际上并未存储在TEE中,而是作为密钥文件存储在/ data / misc / keystore / user_0 /中,由设备加密存储在TEE中的特定密钥。由于设备锁定的更改会擦除KeyStore,因此设备特定密钥似乎来自设备锁定。
出于安全原因,加密密钥文件是有意义的,否则任何root用户都可以读取密钥文件并提取私钥,因为它们可能是清晰的。
所以我有点陷入两难境地。出于可用性考虑,我应该省略setEncryptionRequired(),但出于安全考虑,我应该设置setEncryptionRequired()。
最后,是否可以使用setKeyEntry()将私钥导入硬件支持的KeyStore?我能够做到这一点没有错误,但我不确定它是否是硬件支持。
我的理解是否正确?
答案 0 :(得分:6)
setEncryptionRequired()
在Android 6.0(Marshmallow)中被弃用,并且从未真正实现过。 Android KeyStore的安全性取决于TEE,而不是密码。
您链接到的博客文章已过时,至少在运行Android 6.0或更高版本的设备上已过时。在这些设备上,您不应使用setEncryptionRequired(),并且在卸载应用程序(或完成恢复出厂设置或您的应用程序删除它们)之前,不会删除您的密钥。您的钥匙将由永不离开TEE的密钥安全包裹。实际上,您的密钥永远不会以明文形式留下TEE。使用密钥时,数据将与加密密钥一起传递到TEE。 TEE解包密钥然后处理并返回加密/签名/任何数据。
是的,您可以使用setKeyEntry()导入私钥。如果您想确保您的密钥是硬件支持的,请使用KeyInfo.isInsideSecureHardware()
。例如(来自the documentation):
PrivateKey key = ...; // Android KeyStore key
KeyFactory factory = KeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore");
KeyInfo keyInfo;
boolean isHardwareBacked = false;
try {
keyInfo = factory.getKeySpec(key, KeyInfo.class);
isHardwareBacked = keyInfo.isInsideSecureHardware();
} catch (InvalidKeySpecException e) {
// Not an Android KeyStore key.
}