代码之家  ›  专栏  ›  技术社区  ›  frogatto

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

  •  5
  • frogatto  · 技术社区  · 7 年前

    关于 Android Keystore system 文章,

    关键材料从未进入申请流程。当应用程序使用Android密钥库密钥执行加密操作时,后台明文、密文和要签名或验证的消息将被发送到执行加密操作的系统进程。如果应用程序的进程受到影响,攻击者可能能够使用应用程序的密钥,但无法提取其密钥材料(例如,在Android设备之外使用)。

    所以,我的问题是为什么 BasicAndroidKeyStore ,开发人员能够 get the KeyPair object 然后 print its public/private keys ?

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

    1 回复  |  直到 7 年前
        1
  •  2
  •   Steve Miskovetz    7 年前

    这个 example code 你指的那个 BasicAndroidKeyStore 不将公钥记录为 getPublic() 从keypair类只返回对公钥对象的引用,而不是公钥本身。

    Log.d(TAG, "Public Key reference is: " + kp.getPublic().toString());
    

    原木:

    d/keystorefragment:公钥引用是:android.security.keystore.androidkeystoresapublickey@b8004e8f

    同样的道理 getPrivate() .

    Log.d(TAG, "Private Key reference is: " + kp.getPrivate().toString());
    

    原木:

    d/keystorefragment:私钥引用是 android.security.keystore.androidkeystorersaprivatekey@5da42c27


    现在,正如你在评论中指出的, kp.getPublic().getEncoded() 将返回实际的公钥,但公钥的原始用途并不意味着是秘密的。

    私钥是秘密的,当使用设备安全硬件中支持密钥的硬件支持的密钥库时,密钥安全存储在tee/se中,不能由应用程序本身或其他具有根权限的不良参与者提取。在这个例子中可以看到:

    Log.d(TAG, "Private Key is " + Arrays.toString(kp.getPrivate().getEncoded()));
    

    原木:

    d/keystorefragment:私钥为空


    要验证设备的安全硬件是否支持您的密钥,可以使用此代码的某些变体来满足您的需要。您可以将此代码段粘贴在同一代码段之后 Log.d 上面在示例应用的createKeys()方法中提到。

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