Android 指纹认证
安卓指纹认证使用智能手机触摸传感器对用户进行身份验证。Android Marshmallow(棉花糖)提供了一套API,使用户很容易使用触摸传感器。在Android Marshmallow之前访问触摸传感器的方法不是标准的。
本文地址:http://wuyudong.com/2016/12/15/3146.html,转载请注明出处。
使用安卓指纹认证有几个好处:
1、更快更容易使用
2、安全:指纹可以识别你的身份唯一
3、在线交易更加的容易
在使用android指纹识别之前你必须遵循一些步骤,可能看起来真的很复杂,但本文将教你你一步一步实现。
结果就像下图显示的那样:

开始 Android 指纹认证
就如上面所说,指纹认证过程有以下几个步骤:
- 验证锁屏是否是安全的,或者换句话说,它是用密码或模式保护的
- 确认在智能手机上已经有一个指纹是注册的
- 访问 Android keystore 存储将对象加密/解密的密钥
- 生成一个加密密钥和密码
- 启动认证过程
- 实现一个回调类来处理身份认证事件
就是这些了,下面来实现上面的步骤!
在开始的时候,先得开启触摸传感器与身份认证的权限,在清单文件 Manifest.xml 中添加:
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
现在是时候创建main activity 类来处理所有的认证步骤了.
验证Android安全锁屏
第一步是确认锁屏是否是安全的,这个可以使用 KeyguardManager 和FingerprintManager 来解决。 我们可以通过使用 getSystemService 类获取它们的实例:
// Keyguard Manager
KeyguardManager keyguardManager = (KeyguardManager)
getSystemService(KEYGUARD_SERVICE); // Fingerprint Manager
fingerprintManager = (FingerprintManager)
getSystemService(FINGERPRINT_SERVICE);
现在,我们的认证应用可以检查是否所有的安全判断都满足:
private boolean checkFinger() {
// Keyguard Manager
KeyguardManager keyguardManager = (KeyguardManager)
getSystemService(KEYGUARD_SERVICE);
// Fingerprint Manager
fingerprintManager = (FingerprintManager)
getSystemService(FINGERPRINT_SERVICE);
try {
// Check if the fingerprint sensor is present
if (!fingerprintManager.isHardwareDetected()) {
// Update the UI with a message
message.setText("Fingerprint authentication not supported");
return false;
}
if (!fingerprintManager.hasEnrolledFingerprints()) {
message.setText("No fingerprint configured.");
return false;
}
if (!keyguardManager.isKeyguardSecure()) {
message.setText("Secure lock screen not enabled");
return false;
}
}
catch(SecurityException se) {
se.printStackTrace();
}
return true;
}
注意到应用程序验证了至少有一个指纹已经注册否则认证过程将不会开始,下面的图片展示了如果没有发现注册指纹提示一个错误信息

如果一切就绪,一切判断情况都满足,认证应用产生密钥并访问Android store.

访问Android keystore并生成密钥
接下来的步骤就是访问Android keystore 并产生密钥来加密数据,应用程序在一个叫 generateKey() 的方法中单独完成.
// Get the reference to the key store
keyStore = KeyStore.getInstance("AndroidKeyStore");
接着必须获得密钥生成器的引用:
// Key generator to generate the key
keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES,
"AndroidKeyStore");
最后,我们必须初始化密钥生成器:
keyGenerator.init( new
KeyGenParameterSpec.Builder(KEY_NAME,
KeyProperties.PURPOSE_ENCRYPT |
KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(
KeyProperties.ENCRYPTION_PADDING_PKCS7)
.build()); keyGenerator.generateKey();
注意到我们特别指出密钥的使用: 加密和解密并且认证需要使用密钥,最后应用程序生成了密钥 (最后一行).
上面的代码完整的方法如下:
private void generateKey() throws FingerprintException {
try {
// Get the reference to the key store
keyStore = KeyStore.getInstance("AndroidKeyStore");
// Key generator to generate the key
keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES,
"AndroidKeyStore");
keyStore.load(null);
keyGenerator.init( new
KeyGenParameterSpec.Builder(KEY_NAME,
KeyProperties.PURPOSE_ENCRYPT |
KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(
KeyProperties.ENCRYPTION_PADDING_PKCS7)
.build());
keyGenerator.generateKey();
}
catch(KeyStoreException
| NoSuchAlgorithmException
| NoSuchProviderException
| InvalidAlgorithmParameterException
| CertificateException
| IOException exc) {
exc.printStackTrace();
throw new FingerprintException(exc);
}
}
创建Android Cipher
一旦密钥准备好了,最后步骤就是使用之前生成的密钥来创建Android Cipher ,代码很简单:
private Cipher generateCipher() throws FingerprintException {
try {
Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
SecretKey key = (SecretKey) keyStore.getKey(KEY_NAME,
null);
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher;
}
catch (NoSuchAlgorithmException
| NoSuchPaddingException
| InvalidKeyException
| UnrecoverableKeyException
| KeyStoreException exc) {
exc.printStackTrace();
throw new FingerprintException(exc);
}
}
构建 Android 指纹认证 app
是时候将前面的方法组合起来创建我们的 Android 指纹识别app,这个app很简单只有一个 MainClass 调用上面所示的方法开始认证处理.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); message = (TextView) findViewById(R.id.fingerStatus);
Button btn = (Button) findViewById(R.id.authBtn); final FingerprintHandler fph = new FingerprintHandler(message); if (!checkFinger()) {
btn.setEnabled(false);
}
else {
// We are ready to set up the cipher and the key
try {
generateKey();
Cipher cipher = generateCipher();
cryptoObject =
new FingerprintManager.CryptoObject(cipher);
}
catch(FingerprintException fpe) {
// Handle exception
btn.setEnabled(false);
}
} btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
message.setText("Swipe your finger");
fph.doAuth(fingerprintManager, cryptoObject);
}
});
}
有几点需要注意的,首先,Android app 创建一个 CryptoObject 对象来处理认证过程,接着,app 一个button,当用户点击它的时候认证过程开始,当上面的初始化判断条件不满足的时候这个 button 被隐藏。需要注意的最重要的事情是新类调用FingerprintHandler. 这个类是个接收认证处理事件的回调类,此外, 此类启动认证过程的doauth方法.
Android 指纹认证回调
最后一步是创建一个回调类,这样我们可以接收事件消息并能够知道什么时候认证成功或者除了一些问题,这个类继承自 FingerprintManager.AuthenticationCallback.
public class FingerprintHandler extends FingerprintManager.AuthenticationCallback {
private TextView tv;
public FingerprintHandler(TextView tv) {
this.tv = tv;
}
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
super.onAuthenticationError(errorCode, errString);
tv.setText("Auth error");
}
@Override
public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
super.onAuthenticationHelp(helpCode, helpString);
}
@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
tv.setText("auth ok");
tv.setTextColor(tv.getContext().getResources().
getColor(android.R.color.holo_green_light));
}
@Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
}
public void doAuth(FingerprintManager manager,
FingerprintManager.CryptoObject obj) {
CancellationSignal signal = new CancellationSignal();
try {
manager.authenticate(obj, signal, 0, this, null);
}
catch(SecurityException sce) {}
}
}
有一些重要的方法需要注意,首先,doAuth 开启认证处理,这个方法包含 CryptoObject 对象,一个取消信号和回调监听器。下面的图片显示了app 的响应动作:

这种情况下,用户使用android指纹认证完成了认证。
如何在模拟器上面测试这个app?
要测试这个app,如果有可能使用具有传感器的真机来进行,然而你还可以在模拟器上进行测试app,在使用app之前,你必须配置igure the fingerprint accessing to the Security menu. 当系统要求你的指纹的时候你必须使用adb 命令模拟指纹接触:
adb -e emu finger touch id(like 1,2, ecc.)
最后,当你的指纹搞定,你将得到下面的提示:

最后希望你掌握了android 的指纹识别 api 并知道怎样开发一款指纹识别 app 例子,enjoy 
Android 指纹认证的更多相关文章
- Android指纹识别API讲解,让你有更好的用户体验
我发现了一个比较怪的现象.在iPhone上使用十分普遍的指纹认证功能,在Android手机上却鲜有APP使用,我简单观察了一下,发现Android手机上基本上只有支付宝.微信和极少APP支持指纹认证功 ...
- android指纹识别认证实现
Android从6.0系统支持指纹认证功能 启动页面简单实现 package com.loaderman.samplecollect.zhiwen; import android.annotation ...
- Android 怎样开启与关闭adb 的认证机制(google adb secure) (adb RSA 指纹认证)
前言 欢迎大家我分享和推荐好用的代码段~~声明 欢迎转载,但请保留文章原始出处: CSDN:http://www.csdn.net ...
- android指纹识别、拼图游戏、仿MIUI长截屏、bilibili最美创意等源码
Android精选源码 一个动画效果的播放控件,播放,暂停,停止之间的动画 用 RxJava 实现 Android 指纹识别代码 Android仿滴滴打车(滴滴UI)源码 Android高仿哔哩哔哩动 ...
- Android指纹识别
原文:Android指纹识别 上一篇讲了通过FingerprintManager验证手机是否支持指纹识别,以及是否录入了指纹,这里进行指纹的验证. //获取FingerprintManager实例 F ...
- Android指纹识别深入浅出分析到实战(6.0以下系统适配方案)
指纹识别这个名词听起来并不陌生,但是实际开发过程中用得并不多.Google从Android6.0(api23)开始才提供标准指纹识别支持,并对外提供指纹识别相关的接口.本文除了能适配6.0及以上系统, ...
- Android指纹识别深入浅出分析到实战
指纹识别这个名词听起来并不陌生,但是实际开发过程中用得并不多.Google从Android6.0(api23)开始才提供标准指纹识别支持,并对外提供指纹识别相关的接口.本文除了能适配6.0及以上系统, ...
- Android指纹解锁
Android6.0及以上系统支持指纹识别解锁功能:项目中用到,特此抽离出来,备忘. 功能是这样的:在用户将app切换到后台运行(超过一定的时长,比方说30秒),再进入程序中的时候就会弹出指纹识别的界 ...
- Android OAuth认证
OAuth认证 为了安全地访问在线服务,用户需要在服务上进行身份验证,即要提供他们的身份的证明.对于一个要访问第三方服务的程序来说,安全问题甚至更复杂.不仅仅是用户需要在访问服务前要进行身份验证,而且 ...
随机推荐
- java: web应用中不经意的内存泄露
前面有一篇讲解如何在spring mvc web应用中一启动就执行某些逻辑,今天无意发现如果使用不当,很容易引起内存泄露,测试代码如下: 1.定义一个类App package com.cnblogs. ...
- C语言 · 字符转对比
问题描述 给定两个仅由大写字母或小写字母组成的字符串(长度介于1到10之间),它们之间的关系是以下4中情况之一: 1:两个字符串长度不等.比如 Beijing 和 Hebei 2:两个字符串不仅长度相 ...
- 使用 JavaScript 和 canvas 做精确的像素碰撞检测
原文地址:Pixel accurate collision detection with Javascript and Canvas 译者:nzbin 我正在开发一个需要再次使用碰撞检测的游戏.我通常 ...
- 一个IT人的成长路
毕业四年多了,来深圳三年多了,经历了刚毕业的懵懂少年,成长为现在的成熟稳重青年.职场上,从刚毕业的小白,成长为现在可以成熟应对各种事情的老司机.经历过从初级研发工程师,到中级研发工程师,到高级研发工程 ...
- js学习之函数的参数传递
我们都知道在 ECMAScript 中,数据类型分为原始类型(又称值类型/基本类型)和引用类型(又称对象类型):这里我将按照这两种类型分别对函数进行传参,看一下到底发生了什么. 参数的理解 首先,我们 ...
- 推荐10款超级有趣的HTML5小游戏
HTML5的发展速度比任何人的都想像都要更快.更加强大有效的和专业的解决方案已经被开发......甚至在游戏世界中!这里跟大家分享有10款超级趣味的HTML5游戏,希望大家能够喜欢! Kern Typ ...
- SharePoint 2013: A feature with ID has already been installed in this farm
使用Visual Studio 2013创建一个可视web 部件,当右击项目选择"部署"时报错: "Error occurred in deployment step ' ...
- H3 BPM引擎API接口
引擎API接口通过 Engine 对象进行访问,这个是唯一入口. 示例1:获取组织机构对象 this.Engine.Organization.GetUnit("组织ID"); 示例 ...
- App解读
一直不懂别人口中说的原生开发.混合式开发.今天突然看了一篇文章讲解的是什么叫做原生App?移动 Web App?混合APP?分享给大家. 原生App是专门针对某一类移动设备而生的,它们都是直接安装到设 ...
- Android中实现APP文本内容的分享发送与接收方法简述
谨记(指定选择器Intent.createChooser()) 开始今天的内容前,先闲聊一下: (1)突然有一天头脑风暴,对很多问题有了新的看法和见解,迫不及待的想要分享给大家,文档已经写好了,我需要 ...