安卓密钥库,保护密钥的安全价值

8

我目前正在研究在 Android 4.3 中引入的安全/改进的密钥库。

我想将加密密钥存储在此密钥库中,该密钥用于加密 sqllite 数据库和我的共享首选项中包含的值。

当我查看 SDK 中的 KeyStore 示例时,我看到以下内容:

public static final String ALIAS = "my_key"

如果有人能够反编译我的代码,他们将能够看到明文别名(=从密钥库中检索加密密钥的关键),因此他们将能够获得对我的加密密钥的引用。我该如何安全地管理我的别名?或者我错过了什么重要的点吗?

2个回答

9
以下答案适用于4.3+版本。在此版本中,KeyStore和KeyChain类发生了重大变化。有关更多信息,请参见此处
Keystore访问受到UID的限制——您的应用程序在安装时分配了一个UID。
这就是防止其他应用程序/进程访问您的密钥对/私钥的原因。密钥库守护程序会执行此操作。
这可以选择需要设备PIN进行额外加密。请参见http://developer.android.com/reference/android/security/KeyPairGeneratorSpec.Builder.html#setEncryptionRequired() 使用软件/硬件密钥库的整个目的是解决您描述的情况——即您的应用程序中的任何硬编码数据都可以在反编译时被读取,因此不安全。
@Duncans的答案似乎需要您保留密码。我建议您使用密钥库生成密钥对,然后使用此密钥对加密AES密钥,以便加密您想要的任何内容(比使用RSA密钥快得多)。
您可以像这样使用硬件/软件密钥库支持的私钥:keyStore.getEntry(alias, null);而不传递任何密码。
请参见SecretKeyWrapper.java,以获取一个很好的示例。

那么对于Android 4.3以下的版本,比如ICS,有什么解决方案呢? - NickF
问题是关于在4.3中引入的KeyStore,因此<4.3实际上没有直接的对应物!如果您想在此之前使用秘密密钥,则可能需要包括用户输入和一些PBKDF。话虽如此,<4.3目前占约25%,因此如果您需要支持硬件支持的密钥,则只需支持4.3+即可。 - Dori

1

别名不是敏感信息。每个密钥库都与一个密码相关联,每个密钥也有自己的(可选)密码。这些值必须保持安全。

没有密码,攻击者即使知道别名也无法读取您的密钥材料。


能否指出哪些是密码?我目前正在查看示例中的KeyStoreHelper.java。我可以看到有一个KeyPair对象,它是从KeyPairGenerator生成的。这个对象是否包含私钥和公钥?攻击者是否有可能重新打包我的代码并获得访问这些密钥的权限? - user2987274
1
@user2987274 密码与 KeyStore 类一起使用,用于 loadgetKeysetKeyEntry 方法。在将密钥存储在密钥库中之前,密钥本身没有相关联的密码。因此,新生成的 KeyPair 对象只有在持久化到密钥库中后才有密码。 - Duncan Jones
只是为了确保。如果有人反编译我的代码并获取到ALIAS的引用,那么他们将无法重新打包代码并获取到KeyPair的引用,因此它没有被持久化?或者其他什么东西阻止了该人获取到正确的KeyPair的引用? - user2987274
1
如果您不持久化密钥对,一旦应用程序停止运行,它将不存在。如果您持久化它,您可以选择一个密码来保护密钥。 - Duncan Jones

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接