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);
		}
	}

	public	static 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
	 */

	public	Cipher 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
	 */

	public	boolean 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
	 */
	public	void 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);

猜你喜欢

转载自blog.csdn.net/kangkangjianjian1/article/details/105492672
今日推荐