8

アプリケーションで生体認証を使用していくつかの文字列を暗号化する必要があります。私はこのコードを使用しています:

val promptInfo = BiometricPrompt.PromptInfo.Builder()
        .setTitle("Title")
        .setSubtitle("subtitle")
        .setDescription("description")
        .setNegativeButtonText("button")
        .build()
val cryptoObject = BiometricPrompt.CryptoObject(getEncryptCipher())
val biometricPrompt = BiometricPrompt(requireActivity(), Executors.newSingleThreadExecutor(), object : BiometricPrompt.AuthenticationCallback() {
    override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
        val encodedString1 = Base64.encodeToString(result.cryptoObject?.cipher!!.doFinal(string1), Base64.DEFAULT)
        val encodedString2 = Base64.encodeToString(result.cryptoObject?.cipher!!.doFinal(string2), Base64.DEFAULT) // <- I got a crash in this line
        save(encodedString1, encodedString2)
    }
})
biometricPrompt.authenticate(promptInfo, cryptoObject)


fun getEncryptCipher(): Cipher {
    var keyStore: KeyStore = KeyStore.getInstance("AndroidKeyStore")
    keyStore.load(null)
    if (!isKeyExists()) {
        createKey()
    }
    val key = keyStore.getKey("MyKeyAlias", null)
    val cipher = Cipher.getInstance("${KeyProperties.KEY_ALGORITHM_AES}/${KeyProperties.BLOCK_MODE_CBC}/${KeyProperties.ENCRYPTION_PADDING_PKCS7}")
    cipher.init(Cipher.ENCRYPT_MODE, key)
    return cipher
}

fun createKey() {
    val keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, PROVIDER_ANDROID_KEYSTORE)
    val builder = KeyGenParameterSpec.Builder("MyKeyAlias", KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
            .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
            .setUserAuthenticationRequired(true)
    keyGenerator.init(builder.build())
    keyGenerator.generateKey()
}

適切にエンコードされた最初の文字列。しかし、2 番目の文字列をエンコードしようとすると、クラッシュが発生しました。

java.lang.IllegalStateException: IV has already been used. Reusing IV in encryption mode violates security best practices.
    at android.security.keystore.AndroidKeyStoreUnauthenticatedAESCipherSpi.addAlgorithmSpecificParametersToBegin(AndroidKeyStoreUnauthenticatedAESCipherSpi.java:244)
    at android.security.keystore.AndroidKeyStoreCipherSpiBase.ensureKeystoreOperationInitialized(AndroidKeyStoreCipherSpiBase.java:237)
    at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:495)
    at javax.crypto.Cipher.doFinal(Cipher.java:2055)
    at com.me.myapp.MyFragment$MyMethod$biometricPrompt$1.onAuthenticationSucceeded(MyFragment.kt:49)
    at androidx.biometric.BiometricFragment$2$2.run(BiometricFragment.java:109)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:764)

私が理解しているように、すべての文字列に異なる IV を使用する必要があります。しかし、新しい IV を設定する方法は? BiometricPrompt から IV を受け取りました。

4

1 に答える 1