我们可以从Android密钥库中提取公钥/私钥吗?



关于 Android 密钥库系统文章,

密钥材料永远不会进入申请过程。当应用程序使用 Android 密钥库密钥执行加密操作时,后台的明文、密文和要签名或验证的消息将馈送到执行加密操作的系统进程。如果应用的进程遭到入侵,攻击者可能能够使用应用的密钥,但无法提取其密钥材料(例如,在 Android 设备外部使用(

所以,我的问题是为什么在BasicAndroidKeyStore中,开发人员能够获取KeyPair对象,然后打印其公钥/私钥?

如果开发人员可以访问密钥,那么如何认为此系统是安全的?不是。如果攻击者破坏了应用程序进程,他可以轻松检索 kays 并在设备外部使用。

您从 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");

最新更新