使用生物识别的一种身份验证的加密和解密操作

发布于 2025-01-28 01:34:22 字数 14998 浏览 1 评论 0原文

我已经实施了使用Android的生物识别API加密和解密值的方法。但是我需要阅读一个值,然后再写另一个,并且我不想让用户多次引入指纹。我不知道该怎么做。

我的密码班是:

public class CryptographicUtils {

    private static final String TAG = "CrytographicUtils";

    /**
     * Transforms Byte array into Hexadecimal String.
     *
     * @param buf Byte array to be transformed.
     * @return String.
     */
    public static String asHex(byte[] buf) {
        StringBuilder strum = new StringBuilder(buf.length * 2);
        int i;
        for (i = 0; i < buf.length; i++) {
            if (((int) buf[i] & 0xff) < 0x10) {
                strum.append("0");
            }
            strum.append(Long.toString((int) buf[i] & 0xff, 16));
        }
        return strum.toString();
    }

    /**
     * Transforms Hexadecimal String into Byte array.
     *
     * @param string String to be transformed.
     * @return Byte array,
     */
    public static byte[] fromHexString(String string) {
        int len = string.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(string.charAt(i), 16) << 4)
                    + Character.digit(string.charAt(i + 1), 16));
        }
        return data;
    }

    /**
     * Generates the Biometric Key.
     *
     * @param context Context.
     */
    public static void generateBiometricKey(Context context, String keyAlias, boolean userAuthenticationRequired, int validationTimeout) {
        try {

            KeyGenParameterSpec.Builder spec = new KeyGenParameterSpec.Builder(
                    keyAlias,
                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT);

            spec.setBlockModes(KeyProperties.BLOCK_MODE_CBC);
            spec.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7);
            spec.setKeySize(256);
            spec.setUserAuthenticationRequired(userAuthenticationRequired);
            spec.setUserAuthenticationValidityDurationSeconds(validationTimeout);
            spec.setInvalidatedByBiometricEnrollment(userAuthenticationRequired);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                boolean hasStrongBox = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_STRONGBOX_KEYSTORE);
                spec.setDigests(KeyProperties.DIGEST_SHA256);
                spec.setIsStrongBoxBacked(hasStrongBox);
            }

            generateSecretKey(spec.build());

        } catch (NoSuchProviderException | NoSuchAlgorithmException | InvalidAlgorithmParameterException e) {
            e.printStackTrace();
            Toast.makeText(context,
                    "Authentication error: " + e.getMessage(), Toast.LENGTH_SHORT)
                    .show();
        }
    }

    /**
     * Generates the Biometric Secret Key.
     *
     * @param keyGenParameterSpec Key Generator.
     * @throws NoSuchProviderException            Exception with Security Provider.
     * @throws NoSuchAlgorithmException           Exception with cryptographic algorithm.
     * @throws InvalidAlgorithmParameterException Exception for invalid or inappropriate algorithm parameters.
     */
    private static void generateSecretKey(KeyGenParameterSpec keyGenParameterSpec) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(
                KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
        keyGenerator.init(keyGenParameterSpec);
        keyGenerator.generateKey();
    }

    /**
     * Obtains a Secret Key.
     *
     * @return Secret Key.
     * @throws KeyStoreException         KeyStore exception.
     * @throws CertificateException      Exception of certificate problems.
     * @throws NoSuchAlgorithmException  Exception with cryptographic algorithm.
     * @throws IOException               I/O exception.
     * @throws UnrecoverableKeyException Exception key in the keystore cannot be recovered
     */
    public static SecretKey getSecretKey(String keyAlias) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableKeyException {
        KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");

        // Before the keystore can be accessed, it must be loaded.
        keyStore.load(null);
        return ((SecretKey) keyStore.getKey(keyAlias, null));
    }

    /**
     * Obtains a Cipher.
     *
     * @return Cipher.
     * @throws NoSuchPaddingException   Exception padding mechanism is not available in the environment.
     * @throws NoSuchAlgorithmException Exception with cryptographic algorithm.
     */
    public static Cipher getEncryptCipher(Context context, String keyAlias, boolean userAuthenticationRequired, int validationTimeout) throws NoSuchPaddingException, NoSuchAlgorithmException, KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableKeyException, InvalidKeyException {
        CryptographicUtils.generateBiometricKey(context, keyAlias, userAuthenticationRequired, validationTimeout);
        Cipher res = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
                + KeyProperties.BLOCK_MODE_CBC + "/"
                + KeyProperties.ENCRYPTION_PADDING_PKCS7);
        SecretKey secretKey = getSecretKey(keyAlias);
        res.init(Cipher.ENCRYPT_MODE, secretKey);
        return res;
    }

    public static Cipher getEncryptedCipherWithoutBiometric(String keyAlias) throws NoSuchPaddingException, NoSuchAlgorithmException, UnrecoverableKeyException, CertificateException, KeyStoreException, IOException, InvalidKeyException {
        Cipher res = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
                + KeyProperties.BLOCK_MODE_CBC + "/"
                + KeyProperties.ENCRYPTION_PADDING_PKCS7);
        SecretKey secretKey = getSecretKey(keyAlias);
        res.init(Cipher.ENCRYPT_MODE, secretKey);
        return res;
    }

    /**
     * Obtains a Decrypt Cipher.
     *
     * @throws NoSuchPaddingException             Exception padding mechanism is not available in the environment.
     * @throws NoSuchAlgorithmException           Exception with cryptographic algorithm.
     * @throws InvalidAlgorithmParameterException Exception for invalid or inappropriate algorithm parameters.
     * @throws InvalidKeyException                Exception for invalid Keys.
     */
    public static Cipher getDecryptCipher(String keyAlias, String ivString) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, UnrecoverableKeyException, CertificateException, KeyStoreException, IOException {
        SecretKey secretKey = CryptographicUtils.getSecretKey(keyAlias);
        String algorithm = KeyProperties.KEY_ALGORITHM_AES;
        String blockMode = KeyProperties.BLOCK_MODE_CBC;
        String padding = KeyProperties.ENCRYPTION_PADDING_PKCS7;
        String alg = algorithm + "/" + blockMode + "/" + padding;
        Cipher res = Cipher.getInstance(alg);
        byte[] iv = fromHexString(ivString);
        res.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv));
        return res;
    }

    /**
     * The Cipher created with [getInitializedCipherForEncryption] is used here
     */
    public static String encryptData(String plainText, Cipher cipher) throws  BadPaddingException, IllegalBlockSizeException {
        return asHex(Objects.requireNonNull(Objects.requireNonNull(cipher.doFinal(plainText.getBytes(Charset.defaultCharset())))));
    }

    public static String getIV(Cipher cipher) {
        return asHex(cipher.getIV());
    }

    /**
     * The Cipher created with [getInitializedCipherForDecryption] is used here
     */
    public static String decryptData(String ciphertext, Cipher cipher) throws BadPaddingException, IllegalBlockSizeException {
        byte [] cipherData = fromHexString(ciphertext);
        byte[] passBioByteArray = cipher.doFinal(cipherData);
        return  new String(passBioByteArray, Charset.defaultCharset());
    }

}

下一步是我的生物特征识别方法

  public static void launchBiometricPromptEncrypt(BiometricPromptEncryptListener listener, Context context, String keyAlias, String value, boolean extendValidationTime, BiometricPrompt.PromptInfo promptInfo) {

    if (BiometricUtils.canAuthenticate(context, promptInfo.getAllowedAuthenticators())) {
        NavigationUtils.startHostTransparentFragmentActivity(context, new ActivityCreatedListener() {
            @Override
            public void onCreated() {

                BiometricPrompt biometricPrompt = generateBiometricEncryptPrompt(listener, context, keyAlias, value, extendValidationTime);
                try {
                    if (promptInfo.getAllowedAuthenticators() == Authenticators.BIOMETRIC_STRONG ) {
                        //Authenticate with BIOMETRIC_STRONG
                        Cipher cipher = CryptographicUtils.getEncryptCipher(context, keyAlias, true, (extendValidationTime ? 120 : -1));
                        BiometricPrompt.CryptoObject cryptoObject = new BiometricPrompt.CryptoObject(cipher);
                        biometricPrompt.authenticate(promptInfo, cryptoObject);
                    }
                    else {
                        //Authenticate with BIOMETRIC_WEAK and/or CREDENTIALS
                        biometricPrompt.authenticate(promptInfo);
                    }
                } catch ( Exception e) {
                    NavigationUtils.finishHostTransparentFragmentActivity();
                    listener.onError(...);
                }
            }
        });
    } else {
        NavigationUtils.finishHostTransparentFragmentActivity();
        listener.onError(...);
    }

}

private static BiometricPrompt generateBiometricEncryptPrompt(BiometricPromptEncryptListener listener, Context context, String keyAlias, String value, boolean extendValidationTime) {

    Executor executor = ContextCompat.getMainExecutor(BiometricFragmentActivity.instance);

    //Biometric Prompt
    return new BiometricPrompt(BiometricFragmentActivity.instance, executor, new BiometricPrompt.AuthenticationCallback() {
        @Override
        public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
            super.onAuthenticationError(errorCode, errString);
            NavigationUtils.finishHostTransparentFragmentActivity();
            listener.onError(...);
        }

        @Override
        public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
            super.onAuthenticationSucceeded(result);
            NavigationUtils.finishHostTransparentFragmentActivity();

            try {
                Cipher cipher;
                if (result.getCryptoObject() != null)
                    cipher = result.getCryptoObject().getCipher();
                else
                    cipher = CryptographicUtils.getEncryptCipher(context, keyAlias, true, (extendValidationTime ? 120 : 2));

                String dat = CryptographicUtils.encryptData(value, cipher);
                String iv = CryptographicUtils.getIV(cipher);
                listener.onFinished(dat, iv);
            } catch (Exception ex) {
                listener.onError(...);
            }
        }

        @Override
        public void onAuthenticationFailed() {
            super.onAuthenticationFailed();
        }
    });
}

public static void launchBiometricPromptDecrypt(BiometricPromptDecryptListener listener, Context context, String keyAlias, String biometricDat, String biometricIV, BiometricPrompt.PromptInfo promptInfo) {

    if (BiometricUtils.canAuthenticate(context, promptInfo.getAllowedAuthenticators())) {
        NavigationUtils.startHostTransparentFragmentActivity(context, new ActivityCreatedListener() {
            @Override
            public void onCreated() {

                try {
                    BiometricPrompt biometricPrompt = getBiometricDecrytPrompt(listener, keyAlias, biometricDat, biometricIV);

                    if (promptInfo.getAllowedAuthenticators() == Authenticators.BIOMETRIC_STRONG ) {
                        //Authenticate with BIOMETRIC_STRONG
                        Cipher cipher = CryptographicUtils.getDecryptCipher(keyAlias, biometricIV);
                        BiometricPrompt.CryptoObject cryptoObject = new BiometricPrompt.CryptoObject(cipher);
                        biometricPrompt.authenticate(promptInfo, cryptoObject);
                    }
                    else {
                        //Authenticate with BIOMETRIC_WEAK and/or CREDENTIALS
                        biometricPrompt.authenticate(promptInfo);
                    }

                } catch (KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException | UnrecoverableKeyException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException e) {
                    NavigationUtils.finishHostTransparentFragmentActivity();
                    listener.onError(...);
                }
            }
        });
    } else {
        NavigationUtils.finishHostTransparentFragmentActivity();
        listener.onError(...);
    }

}

private static BiometricPrompt getBiometricDecrytPrompt(BiometricPromptDecryptListener listener, String keyAlias, String biometricDat, String biometricIV) {

    Executor executor = ContextCompat.getMainExecutor(BiometricFragmentActivity.instance);

    //Biometric Prompt
    return new BiometricPrompt(BiometricFragmentActivity.instance,
            executor, new BiometricPrompt.AuthenticationCallback() {
        @Override
        public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
            super.onAuthenticationError(errorCode, errString);
            NavigationUtils.finishHostTransparentFragmentActivity();
            listener.onError(...);
        }

        @Override
        public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
            super.onAuthenticationSucceeded(result);
            NavigationUtils.finishHostTransparentFragmentActivity();

            try {
                Cipher cipher;
                if (result.getCryptoObject() != null)
                    cipher = result.getCryptoObject().getCipher();
                else
                    cipher = CryptographicUtils.getDecryptCipher(keyAlias, biometricIV);

                String valueStoredWithBiometric = CryptographicUtils.decryptData(biometricDat, cipher);
                listener.onFinished(valueStoredWithBiometric);

            } catch (Exception ex) {
                listener.onError(...);
            }
        }

        @Override
        public void onAuthenticationFailed() {
            super.onAuthenticationFailed();
        }
    });
}

可以实现这一behaivour吗?一种指纹身份验证以进行解密和加密?

谢谢

I have implemented methods to encrypt and decrypt values using the Biometric API of android. But I need to read a value and later write another, and I don't want to make the user to introduce the fingerprint more than one time. I don't know how to do that.

My cryptographics class is:

public class CryptographicUtils {

    private static final String TAG = "CrytographicUtils";

    /**
     * Transforms Byte array into Hexadecimal String.
     *
     * @param buf Byte array to be transformed.
     * @return String.
     */
    public static String asHex(byte[] buf) {
        StringBuilder strum = new StringBuilder(buf.length * 2);
        int i;
        for (i = 0; i < buf.length; i++) {
            if (((int) buf[i] & 0xff) < 0x10) {
                strum.append("0");
            }
            strum.append(Long.toString((int) buf[i] & 0xff, 16));
        }
        return strum.toString();
    }

    /**
     * Transforms Hexadecimal String into Byte array.
     *
     * @param string String to be transformed.
     * @return Byte array,
     */
    public static byte[] fromHexString(String string) {
        int len = string.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(string.charAt(i), 16) << 4)
                    + Character.digit(string.charAt(i + 1), 16));
        }
        return data;
    }

    /**
     * Generates the Biometric Key.
     *
     * @param context Context.
     */
    public static void generateBiometricKey(Context context, String keyAlias, boolean userAuthenticationRequired, int validationTimeout) {
        try {

            KeyGenParameterSpec.Builder spec = new KeyGenParameterSpec.Builder(
                    keyAlias,
                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT);

            spec.setBlockModes(KeyProperties.BLOCK_MODE_CBC);
            spec.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7);
            spec.setKeySize(256);
            spec.setUserAuthenticationRequired(userAuthenticationRequired);
            spec.setUserAuthenticationValidityDurationSeconds(validationTimeout);
            spec.setInvalidatedByBiometricEnrollment(userAuthenticationRequired);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                boolean hasStrongBox = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_STRONGBOX_KEYSTORE);
                spec.setDigests(KeyProperties.DIGEST_SHA256);
                spec.setIsStrongBoxBacked(hasStrongBox);
            }

            generateSecretKey(spec.build());

        } catch (NoSuchProviderException | NoSuchAlgorithmException | InvalidAlgorithmParameterException e) {
            e.printStackTrace();
            Toast.makeText(context,
                    "Authentication error: " + e.getMessage(), Toast.LENGTH_SHORT)
                    .show();
        }
    }

    /**
     * Generates the Biometric Secret Key.
     *
     * @param keyGenParameterSpec Key Generator.
     * @throws NoSuchProviderException            Exception with Security Provider.
     * @throws NoSuchAlgorithmException           Exception with cryptographic algorithm.
     * @throws InvalidAlgorithmParameterException Exception for invalid or inappropriate algorithm parameters.
     */
    private static void generateSecretKey(KeyGenParameterSpec keyGenParameterSpec) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(
                KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
        keyGenerator.init(keyGenParameterSpec);
        keyGenerator.generateKey();
    }

    /**
     * Obtains a Secret Key.
     *
     * @return Secret Key.
     * @throws KeyStoreException         KeyStore exception.
     * @throws CertificateException      Exception of certificate problems.
     * @throws NoSuchAlgorithmException  Exception with cryptographic algorithm.
     * @throws IOException               I/O exception.
     * @throws UnrecoverableKeyException Exception key in the keystore cannot be recovered
     */
    public static SecretKey getSecretKey(String keyAlias) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableKeyException {
        KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");

        // Before the keystore can be accessed, it must be loaded.
        keyStore.load(null);
        return ((SecretKey) keyStore.getKey(keyAlias, null));
    }

    /**
     * Obtains a Cipher.
     *
     * @return Cipher.
     * @throws NoSuchPaddingException   Exception padding mechanism is not available in the environment.
     * @throws NoSuchAlgorithmException Exception with cryptographic algorithm.
     */
    public static Cipher getEncryptCipher(Context context, String keyAlias, boolean userAuthenticationRequired, int validationTimeout) throws NoSuchPaddingException, NoSuchAlgorithmException, KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableKeyException, InvalidKeyException {
        CryptographicUtils.generateBiometricKey(context, keyAlias, userAuthenticationRequired, validationTimeout);
        Cipher res = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
                + KeyProperties.BLOCK_MODE_CBC + "/"
                + KeyProperties.ENCRYPTION_PADDING_PKCS7);
        SecretKey secretKey = getSecretKey(keyAlias);
        res.init(Cipher.ENCRYPT_MODE, secretKey);
        return res;
    }

    public static Cipher getEncryptedCipherWithoutBiometric(String keyAlias) throws NoSuchPaddingException, NoSuchAlgorithmException, UnrecoverableKeyException, CertificateException, KeyStoreException, IOException, InvalidKeyException {
        Cipher res = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
                + KeyProperties.BLOCK_MODE_CBC + "/"
                + KeyProperties.ENCRYPTION_PADDING_PKCS7);
        SecretKey secretKey = getSecretKey(keyAlias);
        res.init(Cipher.ENCRYPT_MODE, secretKey);
        return res;
    }

    /**
     * Obtains a Decrypt Cipher.
     *
     * @throws NoSuchPaddingException             Exception padding mechanism is not available in the environment.
     * @throws NoSuchAlgorithmException           Exception with cryptographic algorithm.
     * @throws InvalidAlgorithmParameterException Exception for invalid or inappropriate algorithm parameters.
     * @throws InvalidKeyException                Exception for invalid Keys.
     */
    public static Cipher getDecryptCipher(String keyAlias, String ivString) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, UnrecoverableKeyException, CertificateException, KeyStoreException, IOException {
        SecretKey secretKey = CryptographicUtils.getSecretKey(keyAlias);
        String algorithm = KeyProperties.KEY_ALGORITHM_AES;
        String blockMode = KeyProperties.BLOCK_MODE_CBC;
        String padding = KeyProperties.ENCRYPTION_PADDING_PKCS7;
        String alg = algorithm + "/" + blockMode + "/" + padding;
        Cipher res = Cipher.getInstance(alg);
        byte[] iv = fromHexString(ivString);
        res.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv));
        return res;
    }

    /**
     * The Cipher created with [getInitializedCipherForEncryption] is used here
     */
    public static String encryptData(String plainText, Cipher cipher) throws  BadPaddingException, IllegalBlockSizeException {
        return asHex(Objects.requireNonNull(Objects.requireNonNull(cipher.doFinal(plainText.getBytes(Charset.defaultCharset())))));
    }

    public static String getIV(Cipher cipher) {
        return asHex(cipher.getIV());
    }

    /**
     * The Cipher created with [getInitializedCipherForDecryption] is used here
     */
    public static String decryptData(String ciphertext, Cipher cipher) throws BadPaddingException, IllegalBlockSizeException {
        byte [] cipherData = fromHexString(ciphertext);
        byte[] passBioByteArray = cipher.doFinal(cipherData);
        return  new String(passBioByteArray, Charset.defaultCharset());
    }

}

And the next are my biometric methods

  public static void launchBiometricPromptEncrypt(BiometricPromptEncryptListener listener, Context context, String keyAlias, String value, boolean extendValidationTime, BiometricPrompt.PromptInfo promptInfo) {

    if (BiometricUtils.canAuthenticate(context, promptInfo.getAllowedAuthenticators())) {
        NavigationUtils.startHostTransparentFragmentActivity(context, new ActivityCreatedListener() {
            @Override
            public void onCreated() {

                BiometricPrompt biometricPrompt = generateBiometricEncryptPrompt(listener, context, keyAlias, value, extendValidationTime);
                try {
                    if (promptInfo.getAllowedAuthenticators() == Authenticators.BIOMETRIC_STRONG ) {
                        //Authenticate with BIOMETRIC_STRONG
                        Cipher cipher = CryptographicUtils.getEncryptCipher(context, keyAlias, true, (extendValidationTime ? 120 : -1));
                        BiometricPrompt.CryptoObject cryptoObject = new BiometricPrompt.CryptoObject(cipher);
                        biometricPrompt.authenticate(promptInfo, cryptoObject);
                    }
                    else {
                        //Authenticate with BIOMETRIC_WEAK and/or CREDENTIALS
                        biometricPrompt.authenticate(promptInfo);
                    }
                } catch ( Exception e) {
                    NavigationUtils.finishHostTransparentFragmentActivity();
                    listener.onError(...);
                }
            }
        });
    } else {
        NavigationUtils.finishHostTransparentFragmentActivity();
        listener.onError(...);
    }

}

private static BiometricPrompt generateBiometricEncryptPrompt(BiometricPromptEncryptListener listener, Context context, String keyAlias, String value, boolean extendValidationTime) {

    Executor executor = ContextCompat.getMainExecutor(BiometricFragmentActivity.instance);

    //Biometric Prompt
    return new BiometricPrompt(BiometricFragmentActivity.instance, executor, new BiometricPrompt.AuthenticationCallback() {
        @Override
        public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
            super.onAuthenticationError(errorCode, errString);
            NavigationUtils.finishHostTransparentFragmentActivity();
            listener.onError(...);
        }

        @Override
        public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
            super.onAuthenticationSucceeded(result);
            NavigationUtils.finishHostTransparentFragmentActivity();

            try {
                Cipher cipher;
                if (result.getCryptoObject() != null)
                    cipher = result.getCryptoObject().getCipher();
                else
                    cipher = CryptographicUtils.getEncryptCipher(context, keyAlias, true, (extendValidationTime ? 120 : 2));

                String dat = CryptographicUtils.encryptData(value, cipher);
                String iv = CryptographicUtils.getIV(cipher);
                listener.onFinished(dat, iv);
            } catch (Exception ex) {
                listener.onError(...);
            }
        }

        @Override
        public void onAuthenticationFailed() {
            super.onAuthenticationFailed();
        }
    });
}

public static void launchBiometricPromptDecrypt(BiometricPromptDecryptListener listener, Context context, String keyAlias, String biometricDat, String biometricIV, BiometricPrompt.PromptInfo promptInfo) {

    if (BiometricUtils.canAuthenticate(context, promptInfo.getAllowedAuthenticators())) {
        NavigationUtils.startHostTransparentFragmentActivity(context, new ActivityCreatedListener() {
            @Override
            public void onCreated() {

                try {
                    BiometricPrompt biometricPrompt = getBiometricDecrytPrompt(listener, keyAlias, biometricDat, biometricIV);

                    if (promptInfo.getAllowedAuthenticators() == Authenticators.BIOMETRIC_STRONG ) {
                        //Authenticate with BIOMETRIC_STRONG
                        Cipher cipher = CryptographicUtils.getDecryptCipher(keyAlias, biometricIV);
                        BiometricPrompt.CryptoObject cryptoObject = new BiometricPrompt.CryptoObject(cipher);
                        biometricPrompt.authenticate(promptInfo, cryptoObject);
                    }
                    else {
                        //Authenticate with BIOMETRIC_WEAK and/or CREDENTIALS
                        biometricPrompt.authenticate(promptInfo);
                    }

                } catch (KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException | UnrecoverableKeyException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException e) {
                    NavigationUtils.finishHostTransparentFragmentActivity();
                    listener.onError(...);
                }
            }
        });
    } else {
        NavigationUtils.finishHostTransparentFragmentActivity();
        listener.onError(...);
    }

}

private static BiometricPrompt getBiometricDecrytPrompt(BiometricPromptDecryptListener listener, String keyAlias, String biometricDat, String biometricIV) {

    Executor executor = ContextCompat.getMainExecutor(BiometricFragmentActivity.instance);

    //Biometric Prompt
    return new BiometricPrompt(BiometricFragmentActivity.instance,
            executor, new BiometricPrompt.AuthenticationCallback() {
        @Override
        public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
            super.onAuthenticationError(errorCode, errString);
            NavigationUtils.finishHostTransparentFragmentActivity();
            listener.onError(...);
        }

        @Override
        public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
            super.onAuthenticationSucceeded(result);
            NavigationUtils.finishHostTransparentFragmentActivity();

            try {
                Cipher cipher;
                if (result.getCryptoObject() != null)
                    cipher = result.getCryptoObject().getCipher();
                else
                    cipher = CryptographicUtils.getDecryptCipher(keyAlias, biometricIV);

                String valueStoredWithBiometric = CryptographicUtils.decryptData(biometricDat, cipher);
                listener.onFinished(valueStoredWithBiometric);

            } catch (Exception ex) {
                listener.onError(...);
            }
        }

        @Override
        public void onAuthenticationFailed() {
            super.onAuthenticationFailed();
        }
    });
}

Is there a way to achieve this behaivour? One fingerprint authentication to do a decryption and encryption?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文