密钥认证
原标题:Keystore Key Attestation
链接:https://android-developers.googleblog.com/2017/09/keystore-key-attestation.html
作者:Shawn Willden (软件工程师)
翻译:arjinmc
Android的密钥已经可用多年,为应用程序开发者提供了一种使用加密密钥进行身份验证和加密的方法。密钥将关键材料保留在应用程序的进程空间之外,以便应用程序不会无意中向用户泄露导致被钓鱼,通过其他渠道泄漏,或者在应用程序妥协的情况下将其泄露。许多设备还为安全硬件中的密钥库密钥提供了基于硬件的安全性,从而将关键材料完全保留在Android系统之外,这样即使是Linux内核妥协,关键材料也不会泄漏。在绝大多数Android设备中,安全硬件是主CPU的特殊模式,与Linux内核和Android用户空间进行硬件隔离。另外,有一些设备使用微处理器安全隔离。
Android提供API,允许应用程序确定给定的密钥是否在安全硬件中,但如果操作系统已被破坏,则这些API可能不可靠。密钥认证为设备的安全硬件提供了一种验证非对称密钥是否在安全硬件中的方式,防止对Android操作系统的破坏。
密钥的历史
密钥(Keystore)最初是在Android 4.0中引入的,密钥是用用户密码加密的。在Android 4.1中,添加了使用设备安全硬件的基础架构。
直到Android 6.0,Keystore支持RSA和ECDSA。在Android 6.0中,Keystore显着增强,增加了对AES和HMAC的支持。此外,密码操作的其他关键要素(如RSA padding[标注1:Keystore分别支持用于RSA加密和签名的推荐的OAEP和PSS padding模式,以及较旧的PKCS#1 v1.5模式。]和AES block chaining[标注2:Keystore支持GCM,CBC和ECB block chaining模式。])被移动到安全硬件中。
在Android 6.0中,Keystore还能够限制特定密钥的使用方式。可以应用的最明显的有用限制是用户认证绑定。这使得密钥的使用被“绑定”到用户的密码 - 其PIN,模式或密码或指纹。对于密码验证绑定,应用程序开发者可以指定超时(以秒为单位)。如果用户上次输入密码超过指定时间,则安全硬件拒绝使用该密钥的任何请求。每次使用密钥时,指纹绑定键都需要新的用户认证。
其他更多技术上的限制也可以应用于Android 6.0+ 密钥。具体来说,在密钥创建或导入时,有必要指定可以使用密钥的加密目的(加密,解密,签名或验证),以及padding和block模式,digests,用于初始化向量的源或随机数,以及其他细节的加密密码操作。由于指定的信息是永久地和密码地绑定到密钥材料,所以密钥不允许以任何其他方式使用密钥。因此,控制应用程序或系统的攻击者不能滥用密钥。为了帮助防止攻击,开发者应该为给定的密钥指定最窄的使用范围。
在Android 7.0中引入了Android Keystore最重要的更改之一。具有安全锁屏功能的Android 7.0以上版本的新设备必须具有安全的硬件和支持基于硬件的密码验证和密钥。在Android 7.0之前,安全的硬件支持是普遍的,但在未来几年内,它将变得普及。
在Android 8.0中,对于安装Google Play的所有新设备,都必须提供密钥认证。
为何使用密钥证明?
假设你正在开发应用程序,为银行的客户提供访问其银行余额,交易记录和帐单支付系统的权限。安全是重要的; 你不想让任何拿起用户手机的人访问他们的银行帐户。一种方法是使用用户的网站密码。但这对于用户来说通常常是不方便的,因为网站通常需要长而复杂的密码,这对于小型触摸屏来说是不方便的。
使用Android Keystore,你可以生成一个非对称身份验证密钥,例如256位ECDSA密钥,并让每个用户使用一次复杂的Web密码登录,然后在公司的客户帐户数据库中注册公钥。每次打开应用程序,都可以使用ECDSA密钥执行一个质询 - 响应认证协议。此外,如果你使用密钥认证绑定,用户可以在每次打开应用程序时使用其锁定屏幕密码或指纹进行身份验证。这样他们就可以在手机上使用更简单,更方便的身份验证机制。
如果攻击者妥协Android并尝试提取密钥,则不能被使用因为密钥在安全的硬件中。
作为一个应用程序开发者,密钥认证允许你在服务器上验证你的应用程序请求的ECDSA密钥实际在安全硬件中实时。请注意,在你的应用程序本身中使用认证没有什么意义; 如果Android操作系统是不妥协且值得信赖的,那么你可以使用6.0中介绍的KeyInfo类来发现密钥是否在安全硬件中。如果它被泄露,那么该API以及你在设备上验证证书所做的任何尝试都是不可靠的。
请注意,密钥认证与SafetyNet认证不同。他们是同一个概念,但认证不同的东西,来自不同的地方。Keystore密钥认证确认密钥存在于安全硬件中,具有特定的特征。SafetyNet证明确认设备是真实的(不是模拟器),并且它运行已知的软件。SafetyNet在封面下使用密钥库密钥认证,所以如果你想知道设备的完整性。如果要确认你的密钥在安全的硬件中,请使用钥匙认证。
有关详细信息和示例代码,请参阅developer.android.com上的密钥认证培训文章。