Android 指纹认证
安卓指纹认证使用智能手机触摸传感器对用户进行身份验证。Android Marshmallow(棉花糖)提供了一套API,使用户很容易使用触摸传感器。在Android Marshmallow之前访问触摸传感器的方法不是标准的。
本文地址:http://wuyudong.com/2016/12/15/3146.html,转载请注明出处。
使用安卓指纹认证有几个好处:
1、更快更容易使用
2、安全:指纹可以识别你的身份唯一
3、在线交易更加的容易
在使用android指纹识别之前你必须遵循一些步骤,可能看起来真的很复杂,但本文将教你你一步一步实现。
结果就像下图显示的那样:
开始 Android 指纹认证
就如上面所说,指纹认证过程有以下几个步骤:
- 验证锁屏是否是安全的,或者换句话说,它是用密码或模式保护的
- 确认在智能手机上已经有一个指纹是注册的
- 访问 Android keystore 存储将对象加密/解密的密钥
- 生成一个加密密钥和密码
- 启动认证过程
- 实现一个回调类来处理身份认证事件
就是这些了,下面来实现上面的步骤!
在开始的时候,先得开启触摸传感器与身份认证的权限,在清单文件 Manifest.xml 中添加:
1 | < uses-permission android:name="android.permission.USE_FINGERPRINT" /> |
现在是时候创建main activity 类来处理所有的认证步骤了.
验证Android安全锁屏
第一步是确认锁屏是否是安全的,这个可以使用 KeyguardManager 和FingerprintManager 来解决。 我们可以通过使用 getSystemService 类获取它们的实例:
1 2 3 4 5 6 7 | // Keyguard Manager KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE); // Fingerprint Manager fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE); |
现在,我们的认证应用可以检查是否所有的安全判断都满足:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | 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() 的方法中单独完成.
1 2 | // Get the reference to the key store keyStore = KeyStore.getInstance( "AndroidKeyStore" ); |
接着必须获得密钥生成器的引用:
1 2 3 | // Key generator to generate the key keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore" ); |
最后,我们必须初始化密钥生成器:
1 2 3 4 5 6 7 8 9 10 11 | 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(); |
注意到我们特别指出密钥的使用: 加密和解密并且认证需要使用密钥,最后应用程序生成了密钥 (最后一行).
上面的代码完整的方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | 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 ,代码很简单:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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
调用上面所示的方法开始认证处理.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | @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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | 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 命令模拟指纹接触:
1 | adb -e emu finger touch id(like 1,2, ecc.) |
最后,当你的指纹搞定,你将得到下面的提示:
最后希望你掌握了android 的指纹识别 api 并知道怎样开发一款指纹识别 app 例子,enjoy
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决