Android Keystore 系统如何保证安全?

How the Android Keystore system can be secure?

我阅读了 http://developer.android.com/training/articles/keystore.html 中的 Android 文档 但是我遗漏了一些细节...

如果应用程序使用 AndroidKeyStore 生成密钥(对称或非对称)。

我们可以从那个密钥库中提取密钥吗?

另一个应用程序 (AppB) 可以访问 AppA 生成的密钥吗?

哪些情况下可能丢失钥匙?仅设备出厂重置?

谢谢。

你可以使用普通的KeyStore file or the Android KeyStore Provider

密钥库 (API 1)

您将必须创建一个 KeyStore 文件,并且您还必须管理秘密才能访问它。这个秘密非常敏感,很难对攻击者隐藏。就我个人而言,我更喜欢将责任委派给 Android 系统,这就是为什么我不选择下一个解决方案的原因。

Android 密钥库提供商 (API 18)

使用此 API,您将委托 Android 上管理文件和机密的所有繁重工作。您不需要使用任何密码,因为 OS 本身会存储从您的锁定屏幕 PIN 码、密码、模式和其他变量派生的密码。

如果设备包含嵌入式安全硬件,密钥将存储在那里(例如,可信执行环境 (TEE))。您可以检查 KeyInfo#isInsideSecureHardware() 方法以查看密钥是否保存在那里。这种硬件机制为我们提供了额外的保护,以防我们的应用程序 运行 进入受损的 Linux 内核。

此外,从 Android 9(API 级别 28)开始,StrongBox Keymaster API was introduced for those devices which include a secure chip (like Titan M on Google Pixel 3). If you're running on Android 28 or above, you just need to invoke the setIsStrongBoxBacked(boolean) 方法让 Android 知道您想要使用它(如果它在设备上可用) .尽管上述 TEE 解决方案是可以接受的,但这种使用安全元件 (SE) 的机制是最安全的,因为它基于为安全目的而设计的不同硬件(CPU、内存、存储等) .

这里我们将有一个快速示例,说明如何使用 StrongBox 创建自签名证书和密钥对(如果支持的话):

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore")
        .apply {
            val certBuilder = KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_ENCRYPT)
                .setKeyValidityStart(keyValidityStart)
                .setKeyValidityEnd(keyValidityEnd)
                .setCertificateSerialNumber(BigInteger.valueOf(1L))
                .setCertificateSubject(X500Principal("CN=MyCompany"))

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                initialize(
                    certBuilder
                        .setIsStrongBoxBacked(true) /* Enable StrongBox */
                        .build()
                )
            } else {
                initialize(certBuilder.build())
            }
        }
        .also {
            val keyPair = it.generateKeyPair()
            ...
        }
}

关于您的问题:

Can we extract the key from that KeyStore?

有了它们,您的应用程序可以获得 PrivateKey 并使用它(如果这就是您的意思)。

Can another application (AppB) access the key generated by AppA?

使用 KeyStore 提供程序解决方案,每个应用程序只能访问其 KeyStore 实例或别名。相反,如果另一个应用可以访问该文件,则使用普通的 KeyStore,它可能会尝试攻击它。

In which case we may loose the key? Device Factory reset only?

删除应用程序将删除应用程序的 KeyStore 提供程序实例。但是,由于 Android 的 a nasty bug(在 Android 5 之前更常见),如果用户将锁屏图案更改为密码或只是删除图案,KeyStore 将完全损坏。当用户从 Android 设置中执行“清除凭据”时,也会发生同样的情况。相反,使用经典的 KeyStore,您可以将其存储在外部存储中,即使在设备恢复出厂设置后也能保留它。但是,如前所述,它仍然不如提供商安全。

我在某些方面可能是错误的,但这是我学到的,我只是分享我的经验。希望对您有所帮助。