使用软件/硬件支持的Android Keystore以及可能的安全性/可用性缺陷

我目前正在研究在Android应用程序中存储/使用机密密钥的可能性。 我发现Nikolay Elenkov的博客对这个主题很有帮助,我学到了很多关于Android密钥库和一些基于硬件的实现的东西。

我仍然对安全性和用户体验方面有一些疑问。

软件密钥库

根据我的理解,在此配置中,从用户密码(加上盐以防止彩虹表攻击)导出(使用PBKDF2)主密钥,并用于加密机密。 据我所知,密码是用于锁定屏幕的密码。

在非root用户手机上,只有用户’keystore’能够读/写加密文件,每当应用程序想要访问文件时,都必须调用keystore守护进程,该守护进程检查其UID是否有权访问该文件(授权存储在sqlite数据库中)。

但仍有一些我无法弄清楚的细节:

  • 使用密钥库是否强制使用受密码保护的锁定屏幕?
  • 每次需要访问加密密钥时,用户是否必须输入他/她的密码?
  • 鉴于它是一种纯软件机制,我认为只要密钥操作用于加密操作,密钥总是会在RAM中解密,对吧?

基于硬件的密钥库

至于基于硬件的实现,SoC制造商似乎提供符合[Global Platform TEE][2] (可信执行环境)的解决方案,其中包含嵌入式可信应用程序和API,使Google能够提供其密钥库的硬件支持实现。 因此,可以在TEE中存储密钥,在TEE内部请求创建RSA密钥对,并使用存储在TEE内的密钥来签名或检查数据。 这样,人们就可以使用密钥进行基本的加密操作,而无需离开TEE。

如果我做对了,那么Google密钥库守护程序使用与软件实现中相同的机制来提供对这些密钥的访问控制。 唯一的区别是使用了对存储在TEE中的密钥的引用而不是加密密钥本身。

如果之前说明的所有内容都是正确的,我想在root用户手机上可以修改权限数据库,以便具有任意UID的应用程序可以使用存储在TEE中的任何密钥签名数据。 我对吗 ?

谢谢你的时间!

  • 使用密钥库是否强制使用受密码保护的锁定屏幕?

是的,用户被迫使用锁屏,用密码,别针或图案保护。

  • 每次需要访问加密密钥时,用户是否必须输入他/她的密码?

不,一旦设备被取消,KeyStore也会解锁,无需输入其他密码。 但是,应用程序应检查KeyStore是否已解锁,因为用户可以在“设置”中禁用锁定屏幕保护。 一旦禁用密钥锁定,KeyStore就会变为未初始化,必须再次解锁。

有几次我遇到了一个奇怪的行为,当KeyStore被锁定时,我没有设置锁屏保护。 我被提示输入密码或密码进入KeyStore。 但是,这是不可能的,因为我没有任何密码。 我假设一些系统应用程序锁定了KeyStore。 我不得不重置它以重新初始化。

  • 鉴于它是一种纯软件机制,我认为只要密钥操作用于加密操作,密钥总是会在RAM中解密,对吧?

是的,从KeyStore检索的所有密钥都将驻留在RAM中,直到垃圾收集或取消初始化。 但是你可以在每次需要时获得密钥,而不是将其保存在一些长寿命variables中。

不幸的是,我不熟悉支持HW的KeyStore。 不能说什么。

您对基于TEE的硬件支持方案的分析是正确的。 在TEE中生成的私钥位(不一定符合全球平台规范)永远不会离开TEE,私钥操作在其中执行。

基于TEE的键的句柄存储在Keystore中也是正确的,因此root可以访问和使用它们中的任何一个,或者移动它们以便任何应用程序都可以使用它们。