Reputation: 2524
I'm getting an IllegalBlockSizeException after reading a previously encrypted JSON-String from a file: javax.crypto.IllegalBlockSizeException error:1e00007b:Cipher functions:OPENSSL_internal:WRONG_FINAL_BLOCK_LENGTH
The following code works, when I do not write the String to a file, but directly decrypt the encrypted string:
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)
}
}
I'm reading the string with the following code and converting it to a ByteArray
using 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()
}
This is how the file is written:
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()
}
Upvotes: 0
Views: 1016
Reputation: 9096
Looks like you are writing out a binary file, but reading it in as a text.
How about reading the file with code similar to:
fun readEncrypted(file: String): ByteArray =
FileInputStream(file).use { it.readAllBytes() }
Once you decrypt the ByteArray
you read from the file, you can convert the resulting ByteArray
to a String
.
Upvotes: 1