Android - 如何从指纹认证中获取唯一密钥?

7

我想使用AES加密和解密SD卡中的文件。为了实现这一点,我们总是需要一个种子(通常是由用户作为密码输入的字符串):

public static byte[] generateKey(String password) throws Exception{
   byte[] keyStart = password.getBytes("UTF-8");
   KeyGenerator kgen = KeyGenerator.getInstance("AES");
   SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
   sr.setSeed(keyStart);
   kgen.init(128, sr);
   SecretKey skey = kgen.generateKey();
   return skey.getEncoded();
}

我想跳过这一步(由用户插入密码),仅要求用户通过指纹传感器进行身份验证,然后开始加密过程!
我想知道是否有一种方法可以为触摸指纹传感器的每个不同手指获取唯一密钥,该密钥可用作创建SecretKey的种子!?
我在SO上阅读了一些问题和相关样例,并在github上找到了相关内容,但仍无法找到解决方法。
澄清问题:我已经完成了AES本身的实现,并且完全满意,我只需要找到一种从身份验证后的指纹传感器中获取唯一密钥的方法。

1
指纹不能像密码一样直接用作密钥,因为每次读取指纹时都会略有不同。更糟糕的是,指纹并不是秘密的 - 你到处都留下了指纹。 - President James K. Polk
@JamesKPolk:我对指纹传感器如何检测设备所有者的假设是,指纹传感器根据触摸指纹传感器的每个手指生成哈希密钥。然后,指纹传感器将生成的哈希密钥与保存在某个地方的所有者指纹生成的哈希密钥进行比较(当所有者打算在设备上激活此身份验证时)。 如果存在这样的事情,我需要找到它并将其用作密码(因为我们不知道指纹传感器如何生成哈希密钥,所以这可能是可靠的密码)。 - Jalal Aghazadeh
2
@JalalAghazadeh,与您的问题无关,但您不应在任何代码中使用SHA1PRNG。它已被弃用。 - Shahid Thaika
@JalalAghazadeh 你成功了吗?我正在寻找完全相同的东西,但找不到答案... - ben
@ben 不是很实际 :( 因为正如 "James K Polk" 所提到的,指纹不是秘密,并且你会把它留在任何地方,而且没有全球性 API 可以从指纹芯片获取此类信息,每个公司都有自己的故事。有些公司可以通过一些自定义 API 让你访问这样的密钥,但有些公司则不行! - Jalal Aghazadeh
1个回答

16

更新于2019年10月14日

TL;DR

不,你无法访问指纹。你只能从生物识别API中获得“赞”或“踩”。这是有意设计的。

但是,您可以利用Android Keystore进行硬件支持的加密操作,并要求用户重新验证以释放密钥。这基本上可以实现您想要的功能。

详细回答

从指纹生成类似密码的种子是不可能的。正如James K Polk所评论的那样,当扫描指纹时,指纹会发生变化,而且它们永远不会直接存储在设备上

当指纹被注册时,它的图像被暂时存储在安全设备内存中,然后处理生成验证数据和指纹模板(这些都对Android OS不可访问)。然后原始图像被丢弃。当手指被扫描时,图像与之前生成的验证数据进行比较,如果匹配到一定的准确度,则认为用户已通过身份验证。

生物识别操作在Android的受信任执行环境(TEE)内进行。这是一个完全隔离的操作系统,运行在现代设备上受保护的CPU的受保护部分或单独的协处理器(SE)上。

这是一个几乎无法触及的环境,具有受限界面和硬件屏障,可防止篡改芯片和强制提取生物识别验证数据和加密密钥。

解决方案

回到你最初的问题,不能获取任何唯一的指纹识别。这本质上是不安全的,因为任何应用程序都可以读取秘密!
你可以利用Android的硬件支持的Keystore,并要求设备级身份验证来释放硬件支持的加密密钥(setUserAuthenticationRequired(true))。这意味着生成一个随机秘密,安全地保存在Keystore中,需要滑动手指才能将密钥释放到用户空间。我再次强调“硬件支持”。
您无法控制可以使用哪个手指以及供应商特定实现是否允许绕过生物识别与设备解锁模式等。
Android Keystore Keystore的目的是保护加密密钥。只有在满足了足够的要求后,如最近或立即进行生物识别身份验证,才能检索密钥。
密钥可以受到恶意提取的保护,在现代设备上,硬件绑定,这意味着它们永远不会离开安全硬件(TEE/SE),因此永远不会暴露给您的Android应用程序。任何加密操作,例如AES加密/解密,都是在用户空间之外(在安全硬件上)安全执行的,并且注册新指纹/更改锁定模式将永久使密钥无效。在这种操作模式下,Keystore条目仅作为在安全硬件内进行加密操作的“接口”,真正的秘密永远不会暴露给您的应用程序。
总之

有一个指纹/生物识别API,它完全是为了方便而存在的,允许您通过要求用户进行身份验证来快速确认操作。这归结为TEE / SE的“是” / “否”答案,并且根据手机制造商而大不相同!

Keystore是用于加密密钥的硬件支持保险库。运行API级别28+的设备还可以访问Strongbox Keymaster(如果设备硬件支持),该Keymaster将加密操作限制在具有更安全存储的专用安全CPU上。

这些功能是特定于设备/供应商的!并且可能会受到威胁/不安全!如果您不确定设备,请在启用指纹身份验证之前警告用户。唯一真正安全的加密方法是每次提示用户输入解密密钥(在此情况下,思维是硬件支持的存储)。无论存储在哪里,甚至在实时内存中,始终存在计算风险。

正确地进行密码学非常困难。我强烈建议您在尝试在生产中使用此功能之前研究和理解基础知识以及Android提供的其他安全性。


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