AES шифрование

Как и многие блочные шифры, AES (Advanced Encryption Standard, также известный как Rijndael) поставляется с множеством различных режимов, каждый из которых помечен запутанными трехбуквенными именами, такими как ECB, CBC, CTR или CFB. Многим разработчикам говорят, что им не следует использовать ECB (Electronic Code Book), поскольку она не обеспечивает надежной конфиденциальности данных. Многие предполагают, что очень популярный режим CBC (Cipher Block Chaining) идеально подходит для всех случаев использования. К сожалению, это не так, потому что, обеспечивая очень хорошую конфиденциальность данных, CBC не гарантирует целостность данных.

Что же такое CBC

Первое, что вам нужно знать, прежде чем понять, что такое CBC — это то, что такое блочный шифр. Блочный шифр — это функция, которая берет блок открытого текста (удобочитаемый ввод) длины n и ключ и использует его для создания блока зашифрованного текста (зашифрованной тарабарщины) длины n . AES — самый популярный блочный шифр в настоящее время, так как он рекомендован как NIST, так и NSA, он работает с 128-битными блоками с ключами 128, 192 или 256 бит.

Проблема здесь в том, что функция, предназначенная для ввода 128-битных входных данных, и она не собирается шифровать большой объем данных за один вызов. Столкнувшись с этой проблемой, интуитивное решение состоит в том, чтобы просто разделить ваши данные на несколько 128-битных блоков и просто вызвать AES с одним и тем же ключом для каждого из этих блоков.

ECB-шифрование

Этот метод называется Electronic Code Book и, как я упоминал ранее, небезопасен, потому что шаблоны данных могут остаться и служить основой для анализа. 

CBC стремится решить эту проблему, добавляя случайность к каждому вызову блочного шифра, применяя операцию исключающее ИЛИ (XOR) к каждому блоку открытого текста с ранее сгенерированным блоком зашифрованного текста (или случайным вектором инициализации (IV) для первого блока) . Расшифровка работает, выполняя процесс в обратном порядке и выполняя XOR каждого сгенерированного открытого текста с предыдущим зашифрованным текстом.

CBC-шифрование
CBC-шифрование

Что такое PKCS5Padding

PKCS5Padding указывает на то, каким образом должны обрабатываться неполные блоки. При использовании одного из общих алгоритмов заполнения, нужно включить размер блока в зашифрованные данные, гарантируя то, что когда вы попытаетесь расшифровать зашифрованное сообщение, вы получите нужное количество байт.

Практика

Функции AES шифрования и расшифрования

fun encrypt(str: String, secretKey: String): String {
  val encrypted =
    cipher(Cipher.ENCRYPT_MODE, secretKey).doFinal(str.toByteArray(Charsets.UTF_8))
  return Base64.encodeToString(encrypted, Base64.DEFAULT)
}

fun decrypt(str: String, secretKey: String): String {
  val byteStr = Base64.decode(str.toByteArray(Charsets.UTF_8), Base64.DEFAULT)
  return String(cipher(Cipher.DECRYPT_MODE, secretKey).doFinal(byteStr))
}

private fun cipher(opmode: Int, secretKey: String): Cipher {
   if (secretKey.length != 32) throw RuntimeException("SecretKey length is not 32 chars")
   val c = Cipher.getInstance("AES/CBC/PKCS5Padding")
   val sk = SecretKeySpec(secretKey.toByteArray(Charsets.UTF_8), "AES")
   val iv = IvParameterSpec(secretKey.substring(0, 16).toByteArray(Charsets.UTF_8))
   c.init(opmode, sk, iv)
   return c
}

Генератор SHA 256 bit ключа

fun String.sha256(): String {
  return hashString(this, "SHA-256")
}

// HASH для ключа
private fun hashString(input: String, algorithm: String): String {
  return MessageDigest
    .getInstance(algorithm)
    .digest(input.toByteArray())
    .fold("", { str, it -> str + "%02x".format(it) })
}

Применение функций

val key = "Мой_хитрый_ключ".sha256().substring(0,32)
val text = "Моё сообщение"

// Для шифрования
val encrypt_text = encrypt(text, key)
//encrypt_text = "Абракадабра"

// Для расшифрования
val decrypt_text = decrypt(encrypt_text, key)
//decrypt_text = Моё сообщение
Поделись с друзьями:
Если вам понравилась статья, подписывайтесь на наши социальные сети.

Оставьте комментарий

5 × 3 =