AES-GCM проблема с расшифровкой файлов в Android - PullRequest
0 голосов
/ 19 марта 2019

В моем проекте есть требование загружать и хранить зашифрованные файлы. После исследования я узнал, что 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)
...