From e11685691c66e34bee79c1225963cd9e3565067c Mon Sep 17 00:00:00 2001 From: MazurDorian Date: Wed, 13 Nov 2024 08:38:18 +0200 Subject: [PATCH] fix: IllegalBlockSizeException on Android while decrypting --- .../cipherStorage/CipherStorageBase.kt | 17 +++++++++++- .../CipherStorageKeystoreAesGcm.kt | 27 ------------------- 2 files changed, 16 insertions(+), 28 deletions(-) diff --git a/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorageBase.kt b/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorageBase.kt index f10bff33..6a941bf3 100644 --- a/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorageBase.kt +++ b/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorageBase.kt @@ -1,10 +1,12 @@ package com.oblador.keychain.cipherStorage +import android.annotation.SuppressLint import android.content.Context import android.content.pm.PackageManager import android.os.Build import android.security.keystore.KeyGenParameterSpec import android.security.keystore.KeyInfo +import android.security.keystore.UserNotAuthenticatedException import android.util.Log import androidx.annotation.VisibleForTesting import com.oblador.keychain.SecurityLevel @@ -379,6 +381,7 @@ abstract class CipherStorageBase(protected val applicationContext: Context) : Ci } /** Decrypt provided bytes to a string. */ + @SuppressLint("NewApi") @Throws(GeneralSecurityException::class, IOException::class) protected open fun decryptBytes( key: Key, @@ -391,7 +394,19 @@ abstract class CipherStorageBase(protected val applicationContext: Context) : Ci ByteArrayOutputStream().use { output -> handler?.initialize(cipher, key, input) - CipherInputStream(input, cipher).use { decrypt -> copy(decrypt, output) } + try { + val decrypted = cipher.doFinal(input.readBytes()) + output.write(decrypted) + } catch (e: Exception) { + when { + e is UserNotAuthenticatedException -> throw e + e.cause is android.security.KeyStoreException && + e.cause?.message?.contains("Key user not authenticated") == true -> { + throw UserNotAuthenticatedException() + } + else -> throw e + } + } return String(output.toByteArray(), UTF8) } diff --git a/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorageKeystoreAesGcm.kt b/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorageKeystoreAesGcm.kt index 2f709f37..dc4e6168 100644 --- a/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorageKeystoreAesGcm.kt +++ b/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorageKeystoreAesGcm.kt @@ -229,33 +229,6 @@ class CipherStorageKeystoreAesGcm(reactContext: ReactApplicationContext, private /** Decrypt provided bytes to a string. */ - @Throws(GeneralSecurityException::class, IOException::class) - override fun decryptBytes( - key: Key, - bytes: ByteArray, - handler: DecryptBytesHandler? - ): String { - val cipher = getCachedInstance() - - return try { - if (IV.IV_LENGTH >= bytes.size) - throw IOException("Insufficient length of input data for IV extracting.") - val iv = ByteArray(IV.IV_LENGTH) - System.arraycopy(bytes, 0, iv, 0, IV.IV_LENGTH) - val spec = GCMParameterSpec(IV.TAG_LENGTH, iv) - cipher.init(Cipher.DECRYPT_MODE, key, spec) - - // Decrypt the bytes using cipher.doFinal() - val decryptedBytes = cipher.doFinal(bytes, IV.IV_LENGTH, bytes.size - IV.IV_LENGTH) - String(decryptedBytes, UTF8) - } catch (ex: UserNotAuthenticatedException){ - throw ex - } catch (fail: Throwable) { - Log.w(LOG_TAG, fail.message, fail) - throw fail - } - } - // endregion // region Initialization Vector encrypt/decrypt support