Android Google源生生物识别(Biometric依赖库)

版权归作者所有,转发请注明出处:https://www.jianshu.com/p/ea455240e242

Android Google源生生物识别(FingerprintManager)
Android Google源生生物识别(Biometric依赖库)

前言

Android 6 中引入了FingerprintManager用于集成指纹识别,在后续的更新版本中弃用了FingerprintManager,需要更新到使用Biometric支持库去集成,本文是基于Biometric依赖库进行指纹识别的集成完成指纹登录的流程,设计架构参考 Android Google源生生物识别(FingerprintManager)

touchid.jpg

概览

FingerprintManager

  • Android 6 引入调用指纹传感器
  • Androdi 9 废弃使用BiometricManager替代

FingerprintManagerCompat

  • Android 6 引入FingerprintManager的操作兼容类,包装了FingerprintManager的功能并做了兼容处理
  • Android 9 废弃需要使用依赖库BiometricPrompt替代

BiometricManager

  • Biometric库依赖
  • 提供了生物识别系统信息与生物识别技术(指纹,脸等)
  • 在Android 9 版本和之前版本中会调用FingerprintManagerCompat
  • 在Android 10 版本开始会调用框架层BiometricManager

BiometricPrompt

  • Biometric库依赖
  • 管理系统提供的生物识别提示
  • Android 9 和以上版本将显示一个系统验证的身份验证对话框
  • Android 9 以下仅包含指纹集成,将实现一个自定义的指纹识别身份验证对话框

permission USE_FINGERPRINT

  • Android 6 引入必须添加此权限声明才可以使用指纹功能
  • Android 9 废弃需要使用USE_BIOMETRIC替代

permission USE_BIOMETRIC

  • Android 9 引入必须添加此权限才可使用生物识别功能
  • Biometric库依赖已经添加此权限,故如果使用Biometric库则无需在应用中声明此权限

1.引入Biometric依赖库

Android框架和安全团队发布的生物识别库,这是一个支持库,它取代了所有之前的API迭代。整个库使得所有在Android 10 中公布的特性都可以都可以一直使用到 Android 6

  • 开发人员不再需要代码中判断对应的API等级,因为库在内部处理所有的API匹配。支持库在API 23到API 27无缝使用FingerprintManager,在API 28以上使用BiometricPrompt
  • 开发人员不需要创建自己的UI,该库提供了一个标准的UI
  • 开发人员直接调用一个方法就可以检查设备是否支持生物识别验证

在应用或模块的build.gradle中

dependencies {
    // Java language implementation
    implementation "androidx.biometric:biometric:1.1.0"

    // Kotlin
    implementation "androidx.biometric:biometric-ktx:1.2.0-alpha03"
}

2.检查应用是否可以使用指纹识别

调用BiometricManagercanAuthenticate函数检查当前是否满足使用生物识别的条件,会检查你的设备是否拥有指纹识别硬件,是否已经至少录入一个指纹,是否已经开启指纹验证

Authenticators 定义了身份验证器的类型
BIOMETRIC_STRONG : 满足第三类要求的生物识别传感器
BIOMETRIC_WEAK:满足第二类要求的生物识别传感器
DEVICE_CREDENTIAL:安全设备的要求 (PIN, pattern, or password)

指纹识别传感器的分类决定了生物识别传感器与平台和第三方应用程序接口的能力,传感器在默认情况下被分为第一类,如果他们希望被分类为第二类或者第三类则需要满足更多的附加要求,这取决于传感器的欺骗个冒名顶替率等因素,这意味着您的代码不需要确定生物验证识别的强度,设备制造商会去完成这部分

  • 第一类 :便利
  • 第二类 :弱
  • 第三类 :强

为了提高身份验证的安全性,应用程序在使用生物认证时通常会指定一个CryptoObject,这是因为CryptoObjectKeyStore一起工作以提高额外的安全层,比如银行的App可能需要使用CryptoObject在指纹验证成功之后加解密敏感用户信息,如果你使用到CryptoObject请使用STRONG第三类生物识别技术进行身份验证以确保安全,并且使用CryptoObject还提供了额外的安全,它集成了KeyStore,提供了抵御攻击的弹性,以抵御受威胁的系统,如 root 设备

val result = BiometricManager.from(this)
    .canAuthenticate(BIOMETRIC_STRONG).apply {
        when (this) {
            BiometricManager.BIOMETRIC_SUCCESS -> {
                Log.d("Mike", "BIOMETRIC_SUCCESS")
            }
            BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE -> {
                Log.d("Mike", "BIOMETRIC_ERROR_NO_HARDWARE")
            }
            BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE -> {
                Log.d("Mike", "BIOMETRIC_ERROR_HW_UNAVAILABLE")
            }
            BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> {
                Log.d("Mike", "BIOMETRIC_ERROR_NONE_ENROLLED")
            }
            else -> {
                Log.d("Mike", "else")
            }
        }
    }

注意:Android 10(API 级别 29)及更低版本不支持以下身份验证器类型组合:DEVICE_CREDENTIALBIOMETRIC_STRONG | DEVICE_CREDENTIAL。如需检查 Android 10 及更低版本中是否存在 PIN 码、解锁图案或密码,请使用 KeyguardManager.isDeviceSecure() 方法。

3.创建需要用户授权的密钥

当我们调用指纹传感器时需要生成一个需要用户授权才可以使用的密钥,然后当用户调用指纹传感器识别指纹成功,相当于通过了用户授权然后则可以使用对应的密钥对登录信息进行加密,保存加密信息到内存中,当下次登录时直接可以使用密钥解密密文拿到用户信息自动调用登录Api,从而方便用户使用,要完成以上步骤我们需要完成下列功能

参考 Android Google源生生物识别(FingerprintManager),已经有完整的密钥创建流程

4.配置指纹识别提示UI

我们使用了Biometric依赖库,他可以调用系统提供的对话框在使用它的各个应用之间均保持一致,从而打造更值得信赖的用户体验,使用BiometricPrompt API,

  • 它可以提供重要提示,例如是否需要明确的用户确认(注意: 显示弹框是默认值,如果是用于支付或者交易,或者账户登录,显示确认可以使用 setConfirmationRequired 设置为false,以确保更简化的体验)
  • setNegativeButtonText 设置了取消按钮的描述信息,当用户点击时,onAuthenticationError (errCode errString)接收错误代码ERROR_NEGATIVE_BUTTON
  • 可以设置setDeviceCredentialAllowed(true),选择使用设备密码,图案进行身份验证,但是这和CryptoObject不兼容
val promptInfo = BiometricPrompt.PromptInfo.Builder()
    .setTitle("Register Fingerprint")
    .setSubtitle("Pls Touch the sensor")
    .setNegativeButtonText("Use App Password")
    .build()

4.调用指纹识别传感器进行指纹识别

首选先需要基于BiometricPrompt创建生物验证的callback

val biometricPrompt = BiometricPrompt(
    this,
    ContextCompat.getMainExecutor(this),
    object : BiometricPrompt.AuthenticationCallback() {
        override fun onAuthenticationError(
            errorCode: Int,
            errString: CharSequence
        ) {
            Log.e("Mike", "onAuthenticationError $errorCode $errString")
        }

        override fun onAuthenticationFailed() {
            Log.e("Mike", "onAuthenticationFailed")
        }

        override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
            Log.e("Mike", "onAuthenticationSucceeded")
    })

发起调用指纹传感器

biometricPrompt.authenticate(
    promptInfo,
    BiometricPrompt.CryptoObject(FingerprintCryptographyManager.getCipher(this))
)

5.指纹验证成功并使用密钥加密用户信息

在指纹识别成功之后我们可以获取到经过授权的密钥,然后使用此密钥加密用户信息并且进行存储

override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
    Log.e("Mike", "onAuthenticationSucceeded")
    result.cryptoObject?.cipher?.let {
        FingerprintCryptographyManager.saveCipherTextToSharedPreference(
            context,
            FingerprintCryptographyManager.encyption("abc:123", it)
        )
        FingerprintCryptographyManager.setBindFingerPrintStatus(context, true)
    }
}

6.使用指纹登录并解密用户信息

当你之前已经识别过指纹并且将用户信息加密存储之后,后续的登录操作就可以使用直接使用指纹自动去解密信息并且登录

override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
    Log.e("Mike", "onAuthenticationSucceeded")
    result?.cryptoObject?.cipher?.let {
        val cipherTextFromSharedPreference = FingerprintCryptographyManager.getCipherTextFromSharedPreference(context)
        //TODO use info to login
    }
}

7.指纹识别提示UI不同的效果

屏上指纹 Android 10 屏下指纹 Android 11
屏上指纹 Android 10.jpg
屏下指纹 Android 11.jpg

欢迎关注Mike的简书

Android 知识整理

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容