从文件读取后解密加密的 JSON 字符串时出现 IllegalBlockSizeException

时间:2021-07-04 15:18:26

标签: kotlin encryption cryptography aes javax.crypto

从文件中读取之前加密的 JSON 字符串后,我收到了 IllegalBlockSizeException:javax.crypto.IllegalBlockSizeException error:1e00007b:Cipher functions:OPENSSL_internal:WRONG_FINAL_BLOCK_LENGTH

以下代码有效,当我不将字符串写入文件,而是直接解密加密字符串时:

object Crypto {

    const val BYTEARRAY_LENGTH = 16
    const val ALGORITHM = "AES"
    const val TRANSFORMATION = "AES/CBC/PKCS5PADDING"

    fun getKeyFromPassword(password: String): SecretKey {
        val keyBytes = password.toByteArray()

        if (keyBytes.size != BYTEARRAY_LENGTH) throw IllegalArgumentException("Length of password must be $BYTEARRAY_LENGTH bytes.")

        return SecretKeySpec(keyBytes, ALGORITHM)
    }

    fun encrypt(key: SecretKey, dataToEncrypt: ByteArray): ByteArray {
        val cipher = Cipher.getInstance(TRANSFORMATION)
        cipher.init(Cipher.ENCRYPT_MODE, key, IvParameterSpec(ByteArray(BYTEARRAY_LENGTH)))

        return cipher.doFinal(dataToEncrypt)
    }

    fun decrypt(key: SecretKey, dataToDecrypt: ByteArray): ByteArray {
        val cipher = Cipher.getInstance(TRANSFORMATION)
        cipher.init(Cipher.DECRYPT_MODE, key, IvParameterSpec(ByteArray(BYTEARRAY_LENGTH)))

        return cipher.doFinal(dataToDecrypt)
    }
}

我正在使用以下代码读取字符串并使用 ByteArray 将其转换为 String.toByteArray()

private suspend fun readTextFromUri(uri: Uri): String = withContext(Dispatchers.IO) {
    val stringBuilder = StringBuilder()
    applicationContext.contentResolver.openInputStream(uri)?.use { inputStream ->
        BufferedReader(InputStreamReader(inputStream)).use { reader ->
            var line: String? = reader.readLine()
            while (line != null) {
                stringBuilder.append(line)
                line = reader.readLine()
            }
        }
    }
    return@withContext stringBuilder.toString()
}

文件是这样写的:

val encryptedExport = Crypto.encrypt(key, export.toByteArray())

try {
    withContext(Dispatchers.IO) {
        applicationContext.contentResolver.openFileDescriptor(fileUri, "w")?.use {
            FileOutputStream(it.fileDescriptor).use { stream ->
                stream.write(encryptedExport)
            }
        }
    }
} catch (e: FileNotFoundException) {
    e.printStackTrace()
    return Result.failure()
} catch (e: IOException) {
    e.printStackTrace()
    return Result.failure()
}

1 个答案:

答案 0 :(得分:1)

看起来您正在写出一个二进制文件,但将其作为文本读入。

用类似的代码读取文件怎么样:

fun readEncrypted(file: String): ByteArray =
    FileInputStream(file).use { it.readAllBytes() }

解密从文件中读取的 ByteArray 后,您可以将生成的 ByteArray 转换为 String

相关问题