Шифрование и дешифрование с закрытым ключом KeyStore и iv происходит сбой "Иногда" - PullRequest
0 голосов
/ 13 апреля 2020

Я использую шифрование и дешифрование с KeyStore следующим образом.

Это поток. После того, как я передаю строку в метод шифрования, я сохраняю как зашифрованные, так и iv, чтобы потом можно было восстановить значение с помощью этого. Проблема иногда возникает, некоторые зашифрованные значения не могут быть восстановлены правильно ... не все из них! Так что, думаю, я зашифровал 10 элементов и сохранил их где-то (как зашифрованные, так и iv). Тогда, когда я хочу получить, один из них не может получить правильно!

 init {
        keyStore = KeyStore.getInstance(ANDROID_KEY_STORE)
        keyStore.load(null)
        cipher = Cipher.getInstance("AES/GCM/NoPadding")
    }

  fun encryptData(text: String): Pair<ByteArray, String>? {
        try {
            cipher.init(Cipher.ENCRYPT_MODE, getSecretKet(ALIAS))
            val iv = cipher.iv.toString(Charsets.ISO_8859_1)
            val result = cipher.doFinal(text.toByteArray(Charsets.ISO_8859_1))
            Timber.i("$TAG encrypted data $result")
            Timber.i("$TAG encrypted iv $iv")
            return if (result != null) {
                Pair(result, iv)
            } else {
                null
            }
        } catch (e: Exception) {
            Timber.e("$TAG error encryptData", e)
            return null
        }
    }

fun decryptData(encryptedData: ByteArray, iv: ByteArray): String {
    return try {
        val spec = GCMParameterSpec(128, iv)
        cipher.init(Cipher.DECRYPT_MODE, getSecretKet(ALIAS), spec)
        val result = cipher.doFinal(encryptedData).toString(Charsets.ISO_8859_1)
        Timber.i("$TAG decrypted data $result")
        result
    } catch (e: Exception) {
        Timber.e("$TAG decryptData error may string was not encrypted", e)
        encryptedData.toString()
    }
}

И это для получения секретного ключа. Во-первых, возможно, проблема в моем ключе, поэтому я реализовал его таким образом, и этот класс является одиночным. Но иногда я снова открываю приложение, потому что этот ключ не тот (я думаю, потому что iv и зашифрованное значение, а также шифр исправлены). Я также использую Charsets.ISO_8859_1 . Обратите внимание, что эта кодировка лучше, чтобы сохранить все символы и меньше терять. Тогда я подумал, что проблема может быть в сохранении места, поэтому для теста я просто перехожу из комнаты db с полем sstring в SharePref со строкой. Но проблема та же, так что теперь я уверен, что речь идет не о Savig репозитории.

private fun getSecretKet(alias: String): Key {

    if (keyStore.containsAlias(alias)) {
        //Try for existing key
        return keyStore.getKey(alias, null)
    } else {
        //Key is not present, create new one.
        val keyGenerator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val kGenerator =
                KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE)
            val specs = KeyGenParameterSpec
                .Builder(
                    alias,
                    KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
                )
                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                .build()
            kGenerator.init(specs)
            kGenerator
        } else {
            KeyGenerator.getInstance(ANDROID_KEY_STORE);
        }
        return keyGenerator.generateKey()
    }
}

Я думаю, что это должно работать так же хорошо, как работает в основном, но в конечном итоге я не могу получить некоторые из моих зашифрованных данных как Я упоминал выше. Любое тело есть идеи?

1 Ответ

0 голосов
/ 22 апреля 2020

В конце концов, я решил эту проблему на go глубже, чтобы изменить реализацию AES.

  1. Главное было IV ! В двух словах, Iv - инструмент для более сложного шифрования. Мы создаем IV и передаем его для шифрования, шифрования выполняем шифрование данных и смешивание байтов во многих раундах и для блоков байтов, и в каждом раунде он обновляет IV с помощью логики c и использует его для следующего раунда или блока байтов. Так что, если вы получите IV от шифра после окончательного sh шифрования, вы увидите, что оно изменилось!
  2. Во-вторых, я ввел шифр singleTone, но я изменил его метод шифрования и дешифрования самого создания. Таким образом, у каждой строки для кодирования будет новый IV, и после завершения кодирования я передаю его с зашифрованной строкой для последующего расшифровки.

Сначала я подумал, что это будет из шифрования строк с помощью @PresidentJamesMovelenPolk, но я проверяю это с эта имплементация даже с ISO_8859_1 работает хорошо. И это последняя имплементация:

fun encryptData(text: String): Pair<ByteArray, String>? {
    try {
        val cipher = Cipher.getInstance(TRANSFORMATION)
        cipher.init(Cipher.ENCRYPT_MODE, getSecretKet(ALIAS))
        val iv = cipher.iv
        val result = cipher.doFinal(text.toByteArray(Charsets.ISO_8859_1))
        val resultIv = iv.toString(Charsets.ISO_8859_1)
        Timber.i("$TAG encrypted data $result")
        Timber.i("$TAG encrypted iv $iv")
        return if (result != null) {
            Pair(result, resultIv)
        } else {
            null
        }
    } catch (e: Exception) {
        Timber.e("$TAG error encryptData", e)
        return null
    }
}

fun decryptData(encryptedData: ByteArray, iv: ByteArray): String {
    return try {
        val cipher = Cipher.getInstance(TRANSFORMATION)
        val spec = GCMParameterSpec(128, iv)
        cipher.init(Cipher.DECRYPT_MODE, getSecretKet(ALIAS), spec)
        val result = cipher.doFinal(encryptedData).toString(Charsets.ISO_8859_1)
        Timber.i("$TAG decrypted data $result")
        result
    } catch (e: Exception) {
        Timber.e("$TAG decryptData error may string was not encrypted", e)
        encryptedData.toString()
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...