android监控指纹信息变化,android监听指纹变化(解决反射思路在android10不生效的问题)...

前天偶尔运行代码,一个段异常映入眼帘,我擦android10上反射机制监听不到指纹id等数据了,原因是android10彻底抛弃了之前指纹的api。所以反射不到了。

怎么解决这个问题?我们换个思路当然反射依然可以,不过你需要在android9之前和之后的版本写不同的反射代码,首先之前的反射代码都是我抄的别人的,android10现在还没大神奉献,我也写不出来!!!!(这是关键)

所以我想到了,

根据当前指纹库创建一个密钥 判断秘钥状态来判断指纹库是否发生了改变。是不是很神奇,不是原创的,我也是看见别人给了这样一个思路。

我们设计一个吧!

1.设计一个初始化秘钥的方法(这个方法要可以重新生成和重复利用之前秘钥的功能,为什么?你问我为啥?因为要监听改变就要能获取上次的秘钥所以要可以重复利用秘钥,因为一旦指纹变化了,用户可能需要重置指纹重新设置指纹密码,那么就要重新生成新的秘钥。)

2,需要一个判断指纹是否改变的方法,使用cipher去验证刚才的key,如果指纹改变了会抛异常,捕获和这个异常就可以了。

不说废话了上代码:

package cn.lkk.lkk.util;

import android.content.Context;

import android.content.SharedPreferences;

import android.os.Build;

import android.security.keystore.KeyGenParameterSpec;

import android.security.keystore.KeyPermanentlyInvalidatedException;

import android.security.keystore.KeyProperties;

import android.support.annotation.RequiresApi;

import android.text.TextUtils;

import java.io.IOException;

import java.security.InvalidAlgorithmParameterException;

import java.security.InvalidKeyException;

import java.security.KeyStore;

import java.security.KeyStoreException;

import java.security.NoSuchAlgorithmException;

import java.security.NoSuchProviderException;

import java.security.UnrecoverableKeyException;

import java.security.cert.CertificateException;

import javax.crypto.Cipher;

import javax.crypto.KeyGenerator;

import javax.crypto.NoSuchPaddingException;

import javax.crypto.SecretKey;

/**

* @author lkk

* @date 2019/08/23 10:01

*/

@RequiresApi(api = Build.VERSION_CODES.M)

public class CipherHelper

{

private static CipherHelper instance;

private static final String DEFAULT_KEY_NAME = "defaultKey";

private static final String KEYSTORE_ALIAS = "keyStoreAlias";

private static final String HAS_FINGER_KEY = "hasFingerKey";

private KeyGenerator mKeyGenerator;

private KeyStore keyStore;

private CipherHelper()

{

try

{

keyStore = KeyStore.getInstance("AndroidKeyStore");

}

catch (KeyStoreException e)

{

e.printStackTrace();

}

try

{

mKeyGenerator = KeyGenerator

.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");

}

catch (NoSuchAlgorithmException | NoSuchProviderException e)

{

throw new RuntimeException("Failed to get an instance of KeyGenerator", e);

}

}

publicstatic CipherHelper getInstance()

{

if (instance == null)

{

synchronized (CipherHelper.class)

{

if (instance == null)

{

instance = new CipherHelper();

}

}

}

return instance;

}

/**

* @des 创建cipher

* @author lkk

* @date 2019/08/23 10:05

*/

publicCipher createCipher()

{

try

{

return Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"

+ KeyProperties.BLOCK_MODE_CBC + "/"

+ KeyProperties.ENCRYPTION_PADDING_PKCS7);

}

catch (NoSuchAlgorithmException | NoSuchPaddingException e)

{

e.printStackTrace();

}

return null;

}

/**

* @des 初始化Cipher ,并判断指纹库是否发生了变化

* @author lkk

* @date 2019/08/23 10:17

*/

publicboolean initCipher(Cipher cipher)

{

try

{

keyStore.load(null);

SecretKey key = (SecretKey) keyStore.getKey(KEYSTORE_ALIAS, null);

if (cipher == null)

{

cipher = createCipher();

}

cipher.init(Cipher.ENCRYPT_MODE, key);

return false;

}

catch (KeyPermanentlyInvalidatedException e)

{

return true;

}

catch (KeyStoreException | CertificateException | UnrecoverableKeyException | IOException

| NoSuchAlgorithmException | InvalidKeyException e)

{

return false;

//throw new RuntimeException("Failed to init Cipher", e);

}

}

/**

* @param context

* @param createNewKey 是否创建新的密钥

* @des 根据当前指纹库创建一个密钥

* @author lkk

* @date 2019/08/23 10:30

*/

publicvoid createKey(Context context, boolean createNewKey)

{

if (context == null)

{

throw new RuntimeException("context can not be null");

}

SharedPreferences sharedPreferences = context.getSharedPreferences(DEFAULT_KEY_NAME, Context.MODE_PRIVATE);

try

{

//首先通过标志位判断用户之前是否创建了密钥,如果已经创建过了并且不需要重新创建就跳过

if (TextUtils.isEmpty(sharedPreferences.getString(HAS_FINGER_KEY, "")) || createNewKey)

{

//创建新密钥

KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(KEYSTORE_ALIAS,

KeyProperties.PURPOSE_ENCRYPT |

KeyProperties.PURPOSE_DECRYPT)

.setBlockModes(KeyProperties.BLOCK_MODE_CBC)

.setUserAuthenticationRequired(true)

.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)

{

builder.setInvalidatedByBiometricEnrollment(true);

}

mKeyGenerator.init(builder.build());

mKeyGenerator.generateKey();

sharedPreferences.edit().putString(HAS_FINGER_KEY, "KEY").apply();

}

}

catch (InvalidAlgorithmParameterException e)

{

//throw new RuntimeException(e);

}

}

}

怎么使用呢?

开始监听

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

mCipher = CipherHelper.getInstance().createCipher();

CipherHelper.getInstance().createKey(getActivity(), false);

}

监听判断

if (CipherHelper.getInstance().initCipher(mCipher)){

//关闭指纹登录

//弹窗告知用户

}

重置监听Key

CipherHelper.getInstance().createKey(getActivity(), true);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/363736.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[转载]数据结构笔试题基础

第一章 数据结构与算法 一.算法的基本概念计算机解题的过程实际上是在实施某种算法,这种算法称为计算机算法。 1.算法的基本特征:可行性,确定性,有穷性,拥有足够的情报。 2.算法的基本要素:算法中对数据的运…

random_state ---summary

1-简介 random_state 相当于随机数种子random.seed() 。random_state 与 random seed 作用是相同的。可参考:https://www.jianshu.com/p/4deb2cb2502f 对模型没有影响,但是对于一些进行随机选择的过程有影响。比如随机拆分训练集和测试集。随机种子一致的…

基于cookie的SSO单点登录系统

利用COOKIE实现单点登录功能 近期公司要求帮一个项目实现单点登录功能,在综合考量下决定采用cookie实现,大概的流程如下图所: 转载于:https://www.cnblogs.com/buggeerWang/p/10430770.html

js的栈与堆

JavaScript中基本数据类型和引用数据类型的区别 这是我引用别人的 觉得很好 1、基本数据类型和引用数据类型 ECMAScript包括两个不同类型的值:基本数据类型和引用数据类型。 基本数据类型指的是简单的数据段,引用数据类型指的是有多个值构成的对象。 当…

休眠调试–查找查询的来源

Hibernate为什么在程序的哪个部分以及在哪个部分中生成给定的SQL查询并不总是立即的,尤其是当我们处理的是我们自己编写的代码时。 这篇文章将介绍如何配置Hibernate查询日志记录,并将其与其他技巧一起使用,以找出在程序中执行给定查询的原因…

Java各种对象(PO,BO,VO,DTO,POJO,DAO,Entity,JavaBean,JavaBeans)的区分

PO:持久对象 (persistent object),po(persistent object)就是在Object/Relation Mapping框架中的Entity,po的每个属性基本上都对应数据库表里面的某个字段。完全是一个符合Java Bean规范的纯Java对象,没有增加别的属性和方法。持久…

REMBER

第一句如果我们之间有1000步的距离 你只要跨出第1步我就会朝你的方向走其余的999步 第二句通常愿意留下来跟你争吵的人 才是真正爱你的人第三句付出真心 才会得到真心 却也可能伤得彻底保持距离 就能保护自己 却也注定永远寂寞第四句有时候 不是对方不在乎你 而是你把对…

android 获取程序,Android获取桌面应用程序

转载请注明出处,谢谢:http://blog.csdn.net/harryweasley/article/details/50057029首先在看这个博客之前, 你可以先看下这个博客,http://blog.csdn.net/harryweasley/article/details/50057707里面介绍了两种方式来获取应用程序的…

等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规

随着等保 2.0 时代的到来,网络安全要求更加严格,应用场景更加丰富,等级保护已成为互联网企业义不容辞的责任。作为国内移动安全领域的技术创新企业,几维安全在积极响应等保2.0时代的战略布局,推出等保2.0检测、等保加固…

js中什么是对象,对象的概念是什么?

我们一直在用对象 可是你真的理解对象吗,js中有一个说法是一切皆对象,其实这里说的应该是 一切皆可看作对象 对象就是可以拥有属性和方法的一个集合 士兵就是一个对象,它拥有身高体重的属性,保家卫国,吃饭睡觉的动作方…

在Spring启动时与mongodb一起摇摆

我是Spring Boot的粉丝&#xff0c;这是Spring Boot上的mongodb示例项目。 大多数mongodb示例项目是如此基础&#xff0c;以至于您不会太过分。 您可以搜索普通的Spring Data示例&#xff0c;但是它们可能比您想要的复杂得多。 所以这是我的。 这是我要使用的pom。 <!--?…

android git上传出现错误,热更新上传patch包时提示上传失败,文件不合法

集成配置信息classpath com.android.tools.build:gradle:3.3.2classpath "com.tencent.bugly:tinker-support:1.1.5"distributionUrlhttps://services.gradle.org/distributions/gradle-5.0-all.zipapi com.tencent.bugly:crashreport_upgrade:1.3.6api com.tencent.…

第一章笔记(chapter 1 note

犯错对编程而言非常有教育性. 早期犯的错误越多, 学到的东西就越多.编辑器是提供了编写, 管理, 开发与测试程序的环境, 有时也称为集成开发环境(Integrated Development Environment, IDE).任何环境及任何语言中, 开发程序的编辑, 编译, 链接与执行这四个步骤都是一样的.犯错乃…

又做了3个极品菜[图]

今天的是&#xff1a; 极品豆角炒鸡蛋 极品黄瓜炒鸡蛋 极品炒菠菜没鸡蛋 其他我做的菜请看 《我做的菜很香很好吃[有图]》 转载于:https://www.cnblogs.com/zjneter/archive/2008/04/13/1151383.html

生成器与迭代器

生成器与迭代器一、生成器 1.列表推导式 列表推导式是Python内置的非常简单且强大的可以用来轻松创建列表的方法。它可以使用非常简单的语句利用其他列表创建新的列表。 例如&#xff0c;创建1到10的所有偶数的平方的列表&#xff1a; list [i*i for i in range(1,11) if i%20…

Spring Integration Java DSL示例

现在已经为Spring Integration引入了新的基于Java的DSL &#xff0c;这使得可以使用基于纯Java的配置而不是基于Spring XML的配置来定义Spring Integration消息流。 我尝试使用DSL来获得示例集成流–我称其为Rube Goldberg流 &#xff0c;因为它在尝试大写作为输入传递的字符串…

automake linux,Linux下automake软件编译与发布快速入门

Linux下automake软件编译与发布快速入门2008-04-22eNet&Ciweek进入编辑界面&#xff0c;输入内容如下&#xff1a;AUTOMAKE_OPTIONSforeignbin_PROGRAMSsimserver1 #软件包名称simserver1_SOURCESsimserver1.cpp  #源文件列表&#xff0c;如果有多个则用空格分开LIBS -l…

取消 Vue 中格式编译警告

使用VS Code在学习 Vue 的过程中&#xff0c;博主是在2.0之后开始学习的&#xff0c;在写项目的时候发现控制台经常会报一大堆的警告&#xff0c;都是关于格式的&#xff0c;有时候少空格&#xff0c;有时候多空格&#xff0c;不胜其烦&#xff0c;出现这个问题是因为在初始化的…

常用激活函数(激励函数)理解与总结

转载自https://blog.csdn.net/tyhj_sf/article/details/79932893 什么是激活函数&#xff1f; 神经网络中的每个神经元节点接受上一层神经元的输出值作为本神经元的输入值&#xff0c;并将输入值传递给下一层&#xff0c;输入层神经元节点会将输入属性值直接传递给下一层&#…

[原创]水知道答案吗?(一)

《水知道答案》是一本书的名字&#xff0c;我很有兴趣重复其中的试验&#xff0c;验证其真伪。书中提到的众多试验中&#xff0c;有一个试验最好做。实验内容&#xff1a;初始条件&#xff1a;取三个杯子&#xff0c;倒上相同水源的水&#xff0c;然后每个杯子放进一粒米饭粒。…