从文件读取后解密加密的 JSON-String 时出现 IllegalBlockSizeException
IllegalBlockSizeException when decrypting an encrypted JSON-String after reading from a file
我在从文件中读取先前加密的 JSON-String 后收到 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)
}
}
我正在使用以下代码读取字符串并使用 String.toByteArray()
:
将其转换为 ByteArray
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()
}
看起来您正在写出二进制文件,但将其作为文本读入。
如何使用类似于以下代码读取文件:
fun readEncrypted(file: String): ByteArray =
FileInputStream(file).use { it.readAllBytes() }
解密从文件中读取的 ByteArray
后,您可以将生成的 ByteArray
转换为 String
.
我在从文件中读取先前加密的 JSON-String 后收到 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)
}
}
我正在使用以下代码读取字符串并使用 String.toByteArray()
:
ByteArray
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()
}
看起来您正在写出二进制文件,但将其作为文本读入。
如何使用类似于以下代码读取文件:
fun readEncrypted(file: String): ByteArray =
FileInputStream(file).use { it.readAllBytes() }
解密从文件中读取的 ByteArray
后,您可以将生成的 ByteArray
转换为 String
.