使用指纹秘钥加密解密字符串

由于使用指纹识别功能需要一个加密对象( CryptoObject)该对象一般是由对称加密或者非对称加密获得。
* 纯本地的使用指纹识别功能,只需要对称加密即可;
* 使用指纹识别的对称加密功能的主要流程如下:
* 1、使用 KeyGenerator 创建一个对称密钥,存放在 KeyStore 里。
* 2、设置 KeyGenParameterSpec.Builder.setUserAuthenticationRequired()true
* 3、使用创建好的对称密钥初始化一个 Cipher对象,并用该对象调用 FingerprintManager.authenticate() 方法
* 启动指纹传感器并开始监听。
* 4、重写 FingerprintManager.AuthenticationCallback 的几个回调方法,以处理指纹识别成功( onAuthenticationSucceeded())、
* 失败( onAuthenticationFailed()onAuthenticationError())等情况。


/**
* 指纹秘钥生成工具
* KeyGenerator产生密钥
* KeyStore存放获取密钥
* Cipher,是一个按照一定的加密规则,将数据进行加密后的一个对象
*/
@RequiresApi(api = Build.VERSION_CODES.M)
public class FingerPrintKeyHelper {
    private static KeyGenerator mKeyGenerator;
    private static KeyStore mKeyStore;
    public FingerPrintKeyHelper() {
        AppParam.getInstance().setKeyName("finger_key");
        AppParam.getInstance().setSecretMsg("finger content");
        try {
            mKeyStore = KeyStore.getInstance("AndroidKeyStore");
        } catch (KeyStoreException e) {
            throw new RuntimeException("Failed to get an instance of KeyStore", e);
        }
    }
    /**
     * 创建密钥
     * invalidatedByBiometricEnrollment是false的话,录入新的指纹创建的密钥不会失效
     * 默认是true,true的话,注册新指纹,密钥将失效
     * 7.0以上的系统这个参数才有效
     */
    public void createKey(boolean invalidatedByBiometricEnrollment) {
        try {
            mKeyStore.load(null);
            final KeyGenerator generator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
            final int purpose = KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT;
            final KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(AppParam.getInstance().getKeyName(), purpose);
            builder.setBlockModes(KeyProperties.BLOCK_MODE_CBC);
            builder.setUserAuthenticationRequired(true);//每次使用这个密钥,需要指纹验证
            builder.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7);
            //添加这个会报错:android.security.KeyStoreException: Key user not authenticated
//            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//                builder.setInvalidatedByBiometricEnrollment(invalidatedByBiometricEnrollment);
//            }
            generator.init(builder.build());
            generator.generateKey();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 获取密钥对象
     *
     * @return
     */
    public FingerprintManagerCompat.CryptoObject getCryptoObject(boolean isEncrypt, byte[] IV) {
        try {
            mKeyStore.load(null);
            final SecretKey key = (SecretKey) mKeyStore.getKey(AppParam.getInstance().getKeyName(), null);
            if (null == key) {
                return null;
            }
            final Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_CBC
                    + "/" + KeyProperties.ENCRYPTION_PADDING_PKCS7);
            if (isEncrypt) {
                cipher.init(Cipher.ENCRYPT_MODE, key);
            } else {
                cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(IV));
            }
            return new FingerprintManagerCompat.CryptoObject(cipher);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}



/**
     * 指纹解密需要的初始化向量参数
     */
    String IV = "iv";
    /**
     * 用来指纹加密的字符串
     */
    String SECRET_MESSAGE = "Very secret message";
    /**
     * 指纹加密后的字符串
     */
    String ENCRYPT_STR = "encrypt_str";
    /**
     * 指纹密码生成的密钥
     */
    String KEY_NAME = "key_name";

指纹秘钥工具类使用:
private FingerPrintKeyHelper keyHelper;
keyHelper = new FingerPrintKeyHelper();

//加密模式,创建key
          keyHelper.createKey(false);

//初始化加密对象
private boolean initCrypto() {
        mCryptoObject = keyHelper.getCryptoObject(isEncrypt, Base64.decode(AppParam.getInstance().getIV(), Base64.URL_SAFE));
        if (null != mCryptoObject) {
            return true;
        } else {
            return false;
        }
}


//加密解密字符串
Cipher cipher = result.getCryptoObject().getCipher();
        if (null == cipher) {
            return;
        }
        if (isEncrypt) {
            try {
                byte[] secretMsg = cipher.doFinal((AppParam.getInstance().getSecretMsg()).getBytes());
                byte[] IV = cipher.getIV();
                AppParam.getInstance().setIV(Base64.encodeToString(IV, Base64.URL_SAFE));
                AppParam.getInstance().setEncryptStr(Base64.encodeToString(secretMsg, Base64.URL_SAFE));
                if (null != listener) {
                    listener.onSuccess();
                }
            } catch (IllegalBlockSizeException | BadPaddingException e) {
                e.printStackTrace();
            }
        } else {
            String encryptStr = AppParam.getInstance().getEncryptStr();
            if (null == encryptStr) {
                listener.onFail();
            }
            try {
                byte[] decryptMsg = cipher.doFinal(Base64.decode(encryptStr, Base64.URL_SAFE));
                String decryStr = new String(decryptMsg);
                if (null != listener) {
                    if (decryStr.equals(AppParam.getInstance().getSecretMsg())) {
                        listener.onSuccess();
                    } else {
                        listener.onFail();
                    }
                }
            } catch (IllegalBlockSizeException | BadPaddingException e) {
                e.printStackTrace();
            }
        }

猜你喜欢

转载自blog.csdn.net/hpp_1225/article/details/79412651