关键材料永远不会进入申请流程。当应用程序使用Android密钥库密钥执行加密操作时,在幕后将纯文本,密文以及要签名或验证的消息馈送到执行加密操作的系统进程。如果应用程序的进程受到威胁,则攻击者可能可以使用应用程序的密钥,但无法提取其密钥材料(例如,在Android设备外部使用)
所以,我的问题是为什么在BasicAndroidKeyStore中,开发人员能够先get the KeyPair object,然后再print its public/private keys?
如果开发人员可以访问密钥,那么该系统如何被视为安全?不是。如果攻击者破坏了应用程序的进程,则他可以轻松地检索到凯斯并在设备外部使用。
答案 0 :(得分:2)
您从example code指向的BasicAndroidKeyStore不会将公钥记录为KeyPair类中的getPublic(),只会返回对公钥对象的引用,而不会返回公钥本身
Log.d(TAG, "Public Key reference is: " + kp.getPublic().toString());
日志:
D / KeyStoreFragment:公钥参考是:android.security.keystore.AndroidKeyStoreRSAPublicKey@b8004e8f
getPrivate()也是如此。
Log.d(TAG, "Private Key reference is: " + kp.getPrivate().toString());
日志:
D / KeyStoreFragment:私钥参考是 android.security.keystore.AndroidKeyStoreRSAPrivateKey@5da42c27
现在,正如您在评论中指出的那样,kp.getPublic().getEncoded()
将返回实际的公共密钥,但是公共密钥的原始用途并不意味着是秘密的。
私钥是秘密的,并且在使用硬件支持的密钥库并在设备的安全硬件中支持密钥的同时,私钥被安全地存储在TEE / SE中,并且不能由应用程序本身或其他不良应用程序提取。具有root特权的演员。您可以在此示例中看到它:
Log.d(TAG, "Private Key is " + Arrays.toString(kp.getPrivate().getEncoded()));
日志:
D / KeyStoreFragment:私钥为空
要验证设备的安全硬件是否支持您的密钥,可以使用此代码的一些变体来满足您的需求。您可以将此代码段粘贴到示例应用程序的createKeys()方法中与上述Log.d相同的位置。
KeyFactory factory = KeyFactory.getInstance(kp.getPrivate().getAlgorithm(), "AndroidKeyStore");
KeyInfo keyInfo = null;
try {
keyInfo = factory.getKeySpec(kp.getPrivate(), KeyInfo.class);
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
if (keyInfo.isInsideSecureHardware())
Log.d(TAG, "Key is supported in secure hardware");
else
Log.d(TAG, "Key is not supported in secure hardware");