安卓指纹认证使用智能手机触摸传感器对用户进行身份验证。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 指纹认证的更多相关文章

  1. Android指纹识别API讲解,让你有更好的用户体验

    我发现了一个比较怪的现象.在iPhone上使用十分普遍的指纹认证功能,在Android手机上却鲜有APP使用,我简单观察了一下,发现Android手机上基本上只有支付宝.微信和极少APP支持指纹认证功 ...

  2. android指纹识别认证实现

    Android从6.0系统支持指纹认证功能 启动页面简单实现 package com.loaderman.samplecollect.zhiwen; import android.annotation ...

  3. Android 怎样开启与关闭adb 的认证机制(google adb secure) (adb RSA 指纹认证)

    前言         欢迎大家我分享和推荐好用的代码段~~声明         欢迎转载,但请保留文章原始出处:          CSDN:http://www.csdn.net           ...

  4. android指纹识别、拼图游戏、仿MIUI长截屏、bilibili最美创意等源码

    Android精选源码 一个动画效果的播放控件,播放,暂停,停止之间的动画 用 RxJava 实现 Android 指纹识别代码 Android仿滴滴打车(滴滴UI)源码 Android高仿哔哩哔哩动 ...

  5. Android指纹识别

    原文:Android指纹识别 上一篇讲了通过FingerprintManager验证手机是否支持指纹识别,以及是否录入了指纹,这里进行指纹的验证. //获取FingerprintManager实例 F ...

  6. Android指纹识别深入浅出分析到实战(6.0以下系统适配方案)

    指纹识别这个名词听起来并不陌生,但是实际开发过程中用得并不多.Google从Android6.0(api23)开始才提供标准指纹识别支持,并对外提供指纹识别相关的接口.本文除了能适配6.0及以上系统, ...

  7. Android指纹识别深入浅出分析到实战

    指纹识别这个名词听起来并不陌生,但是实际开发过程中用得并不多.Google从Android6.0(api23)开始才提供标准指纹识别支持,并对外提供指纹识别相关的接口.本文除了能适配6.0及以上系统, ...

  8. Android指纹解锁

    Android6.0及以上系统支持指纹识别解锁功能:项目中用到,特此抽离出来,备忘. 功能是这样的:在用户将app切换到后台运行(超过一定的时长,比方说30秒),再进入程序中的时候就会弹出指纹识别的界 ...

  9. Android OAuth认证

    OAuth认证 为了安全地访问在线服务,用户需要在服务上进行身份验证,即要提供他们的身份的证明.对于一个要访问第三方服务的程序来说,安全问题甚至更复杂.不仅仅是用户需要在访问服务前要进行身份验证,而且 ...

随机推荐

  1. Docker笔记一:基于Docker容器构建并运行 nginx + php + mysql ( mariadb ) 服务环境

    首先为什么要自己编写Dockerfile来构建 nginx.php.mariadb这三个镜像呢?一是希望更深入了解Dockerfile的使用,也就能初步了解docker镜像是如何被构建的:二是希望将来 ...

  2. jsp页面无法识别el表达式的解决方案

    今天在写一个springmvc的小demo时,碰到一个问题,在jsp页面中书写为${user.username}的表达式语言,在浏览器页面中仍然显示为${user.username},说明jsp根本不 ...

  3. PHP与JAVA构造函数的区别

    早期的PHP是没有面向对象功能的,但是随着PHP发展,从PHP4开始,也加入了面向对象.PHP的面向对象语法是从JAVA演化而来,很多地方类似,但是又发展出自己的特色.以构造函数来说,PHP4中与类同 ...

  4. 代码的坏味道(16)——纯稚的数据类(Data Class)

    坏味道--纯稚的数据类(Data Class) 特征 纯稚的数据类(Data Class) 指的是只包含字段和访问它们的getter和setter函数的类.这些仅仅是供其他类使用的数据容器.这些类不包 ...

  5. 自己实现简单Spring Ioc

    IoC则是一种 软件设计模式,简单来说Spring通过工厂+反射来实现IoC. 原理简单说明: 其实就是通过解析xml文件,通过反射创建出我们所需要的bean,再将这些bean挨个放到集合中,然后对外 ...

  6. XAMARIN ANDROID 二维码扫描示例

    现在二维码的应用越来越普及,二维码扫描也成为手机应用程序的必备功能了.本文将基于 Xamarin.Android 平台使用 ZXing.Net.Mobile  做一个简单的 Android 条码扫描示 ...

  7. Atitit.软件开发的三层结构isv金字塔模型

    Atitit.软件开发的三层结构isv金字塔模型 第一层,Implements 层,着重与功能的实现.. 第二次,spec层,理论层,设计规范,接口,等.流程.方法论 顶层,val层,价值观层,原则, ...

  8. 为什么你SQL Server的数据库文件的Date modified没有变化呢?

    在SQL Server数据库中,数据文件与事务日志文件的修改日期(Date Modified)是会变化的,但是有时候你会发现你的数据文件或日志文件的修改日期(Date Modified)几个月甚至是半 ...

  9. 2003-Can't connect to mysql server on localhost (10061)

    mysql数据库出现2003-Can't connect to mysql server on localhost (10061)问题 解决办法:查看wampserver服务器是否启动,如果没有启动启 ...

  10. Oracle中的commit详解

    本文转自 : http://blog.csdn.net/hzhsan/article/details/9719307 它执行的时候,你不会有什么感觉.commit在数据库编程的时候很常用,当你执行DM ...