В моем проекте есть требование загружать и хранить зашифрованные файлы. После исследования я узнал, что AES с GCM отвечает моим требованиям. Я сделал демонстрационное приложение в качестве доказательства концепции. Мой код работает нормально, когда я пытаюсь зашифровать и расшифровать строки. Я считаю, что шифрование работает, потому что я получаю файл того же размера, что и исходный файл. Проблема в том, что когда я расшифровываю зашифрованный файл, он показывает исключение как
javax.crypto.AEADBadTagException: ошибка: 1e000065: шифр
Функции: OPENSSL_internal: BAD_DECRYPT
Вот мой код
Шифрование
fun encrypt(data : ByteArray, iv : ByteArray, secretKey : SecretKey) : ByteArray{
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
val parameterSpec = GCMParameterSpec(128, iv)
cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec)
val encrypted = cipher.doFinal(data)
val byteBuffer = ByteBuffer.allocate(4 + iv.size + encrypted.size)
byteBuffer.putInt(iv.size)
byteBuffer.put(iv)
byteBuffer.put(encrypted)
val cipherMessage = byteBuffer.array()
return cipherMessage
}
дешифрования
fun decrypt(cipherMessage : ByteArray, key : SecretKey) : ByteArray{
val byteBuffer = ByteBuffer.wrap(cipherMessage)
val ivLength = byteBuffer.int
if (ivLength < 12 || ivLength >= 16) {
throw IllegalArgumentException("invalid iv length")
}
val iv = ByteArray(ivLength)
byteBuffer.get(iv)
val cipherText = ByteArray(byteBuffer.remaining())
byteBuffer.get(cipherText)
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipher.init(Cipher.DECRYPT_MODE, key, GCMParameterSpec(128, iv))
val plainText = cipher.doFinal(cipherText)
return plainText
}
Генерация ключей
val secureRandom = SecureRandom()
val key = ByteArray(16)
secureRandom.nextBytes(key)
val secretKey = SecretKeySpec(key, "AES")
val iv = ByteArray(12)
secureRandom.nextBytes(iv)
и я использую следующий код для чтения и записи файла на диск, для простоты я опускаю нерелевантные коды.
Чтение, шифрование и запись
do {
count = input.read(data)
if (count == -1)
break
total += count
output.write(encrypt(data, iv, secretKey), 0, count)
} while (true)
Чтение, дешифрование и запись
do {
count = input2.read(data)
Log.e("Worker", "Count:$count")
if (count == -1)
break
total += count
output2.write(decrypt(data, secretKey), 0, count)
} while (true)