簡體   English   中英

android 使用指紋解密文件

[英]android decrypt file using fingerprint

使用下面的代碼,我可以使用用戶輸入的密碼輕松加密和解密文件。 我現在正在使用指紋進入我的應用程序。 當指紋正確時,我想解密文件。 但是如果用戶沒有輸入密碼怎么辦? 有沒有相對安全的方法來做到這一點? 謝謝

public class CryptoUtils {

private static final String ALGORITHM = "AES";
private static final String ENCRYPTION_IV = "4e5Wa71fYoT7MFEX";
private static String ENCRYPTION_KEY = "";

public static void encrypt(String key, File inputFile, File outputFile)
        throws CryptoException {
    doCrypto(Cipher.ENCRYPT_MODE, key, inputFile, outputFile);
}

public static void decrypt(String key, File inputFile, File outputFile)
        throws CryptoException {
    doCrypto(Cipher.DECRYPT_MODE, key, inputFile, outputFile);
}

private static void doCrypto(int cipherMode, String key, File inputFile, File outputFile)
        throws CryptoException {
    try {

        ENCRYPTION_KEY = key;

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(cipherMode, makeKey(), makeIv());

        FileInputStream inputStream = new FileInputStream(inputFile);
        byte[] inputBytes = new byte[(int) inputFile.length()];
        inputStream.read(inputBytes);

        byte[] outputBytes = cipher.doFinal(inputBytes);
        FileOutputStream outputStream = new FileOutputStream(outputFile);
        outputStream.write(outputBytes);

        inputStream.close();
        outputStream.close();
        //Log.d("cur__", "Encryption/Decryption Completed Succesfully");
    } catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException | IOException ex) {
        throw new CryptoException("Error encrypting/decrypting file " + ex.getMessage(), ex);
    } catch (InvalidAlgorithmParameterException ex) {
        Logger.getLogger(CryptoUtils.class.getName()).log(Level.SEVERE, null, ex);
    }
}

private static AlgorithmParameterSpec makeIv() {
    return new IvParameterSpec(ENCRYPTION_IV.getBytes(StandardCharsets.UTF_8));
}

private static Key makeKey() {
    try {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] key = md.digest(ENCRYPTION_KEY.getBytes(StandardCharsets.UTF_8));
        //Log.d("Lenghtis", new SecretKeySpec(key, ALGORITHM).getEncoded().length + "");
        return new SecretKeySpec(key, ALGORITHM);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return null;
}

}

您首先需要生成一個密鑰。 您可以使用以下 function

fun generateKey(storeKey: StoreKey): SecretKey {

    val keyGenerator =
        KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "MyKeyStore")

    val keyGenParameterSpec = KeyGenParameterSpec.Builder(storeKey.Alias,
        KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
        .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
        .setUserAuthenticationRequired(true)
        .setRandomizedEncryptionRequired(false)
        .build()

    keyGenerator.init(keyGenParameterSpec)
    return keyGenerator.generateKey()
}

您需要 setUserAuthenticationRequired(true) 進行生物特征認證。

然后,您可以將此密鑰提供給您的生物特征驗證器以對用戶進行身份驗證,作為回報,您將從它那里收到密碼。

然后,您可以使用該密碼(加密密碼或解密密碼)直接使用此密碼執行加密/解密數據。

androidx.biometric:biometric:1.0.0-beta01

像這樣

val biometricCallbacks = object : BiometricPrompt.AuthenticationCallback() {
        override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
            super.onAuthenticationSucceeded(result)

            result.cryptoObject?.cipher?.let { cipher ->
                val encryptedData = cipherUtils.encryptAES(dataToEncrypt, cipher)
                dismiss()
            }
        }

        override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
            super.onAuthenticationError(errorCode, errString)

            if (errorCode == BiometricPrompt.ERROR_CANCELED || errorCode == BiometricPrompt.ERROR_USER_CANCELED) {
                dismiss()
            }
        }

        override fun onAuthenticationFailed() {
            super.onAuthenticationFailed()
            Log.e("BIOMETRIC", "FAILED")
        }
    }

    val biometricPrompt = BiometricPrompt(this, biometricExecutor, biometricCallbacks)

    val biometricPromptInfo = BiometricPrompt.PromptInfo.Builder()
        .setTitle("APP")
        .setSubtitle("Enable Biometric for Encryption")
        .setDescription("")
        .setNegativeButtonText("Cancel")
        .build()

    biometricPrompt.authenticate(
        biometricPromptInfo,
        BiometricPrompt.CryptoObject(
            cipherUtils.getBioEncryptCipher(keyStoreUtils.generateNewKey(StoreKey.Pass, true))
        )
    )

您可以加密用戶密碼並將其安全地保存在某處的數據庫中並使用生物特征認證。 由於您生成的密鑰嚴格綁定到用戶的生物特征,因此用戶加密的密碼不會被泄露。

這是使用生物特征綁定密鑰的 androidx.biometric 演示應用程序(密鑰只能通過強大的生物特征傳感器解鎖)。

基本上

  1. 生成一個僅在通過生物特征驗證后才能使用的密鑰,以及您希望該密鑰能夠執行的相關功能(加密、解密等)
  2. 將您希望執行的加密操作包裝在CryptoObject中。 密鑰只有在用戶通過生物識別認證后才能使用
  3. Invoke BiometricPrompt#authenticate(CryptoObject)
  4. onAuthenticationSucceeded之后使用密鑰

為了完整起見,還有身份驗證綁定密鑰(密鑰可以通過生物識別設備憑據解鎖),只要用戶在t秒內完成身份驗證,您的應用程序就可以使用這些密鑰,其中tKeyGenParameterSpec.Builder#setUserAuthenticationValidityDurationSeconds中指定。 您可以在此處查看示例用法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM