Blowfish шифрование

Теоретическая часть

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

Blowfish был разработан Брюсом Шнайером специально для использования в средах с ограниченной производительностью. Он был тщательно проанализирован и признан криптографическим сообществом «достаточно безопасным».

Blowfish требует около 5 КБ памяти. Тщательная реализация на 32-битном процессоре может зашифровать или расшифровать 64-битное сообщение приблизительно за 12 тактов, а не очень осторожные реализации, не увеличивают это время намного. Более длинные сообщения увеличивают время вычислений линейным образом; например, 128-битное сообщение занимает примерно (2 x 12) тактов. Blowfish работает с ключами длиной до 448 бит.

Рисунок 1: Алгоритм Blowfish

Графическое представление алгоритма Blowfish представлено на рисунке 1. В этом описании 64-битное открытое текстовое сообщение сначала делится на 32 бита. «Левые» 32 бита объединяются по схеме XOR с первым элементом P-массива для создания значения, которое я назову P’, прогоняется через функцию преобразования F, затем выполняется операция XOR с «правильными» 32 битами сообщения для получения новое значение я назову F’. Затем F’ заменяет «левую» половину сообщения, а P’ заменяет «правую» половину, и процесс повторяется еще 15 раз с последовательными элементами P-массива. Полученные P’ и F’ затем объединяются по схеме XOR с двумя последними записями в P-массиве (записи 17 и 18) и рекомбинируются для получения 64-битного зашифрованного текста.

Рисунок 2: Графическое представление F

Графическое представление F показано на рис. 2. Функция делит 32-битный ввод на четыре байта и использует их в качестве индексов в S-массиве. Затем результаты поиска складываются и объединяются XOR для получения вывода. Поскольку Blowfish является симметричным алгоритмом, для расшифровки и шифрования используется одна и та же процедура. Единственное отличие состоит в том, что вводом для шифрования является открытый текст, а для расшифровки вводом является зашифрованный текст.

Значения P-массива и S-массива, используемые Blowfish, предварительно вычисляются на основе ключа пользователя. По сути, ключ пользователя преобразуется в P-массив и S-массив, а сам ключ может быть отброшен после преобразования. P-массив и S-массив не нужно пересчитывать (пока не меняется ключ), но они должны оставаться секретными.

Практическая часть

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

fun encrypt(password: String, key: String): String {
  val KeyData = key.toByteArray()
  val KS = SecretKeySpec(KeyData, "Blowfish")
  val cipher = Cipher.getInstance("Blowfish")
  cipher.init(Cipher.ENCRYPT_MODE, KS)
  return Base64.encodeToString(cipher.doFinal(password.toByteArray(charset("UTF-8"))), Base64.DEFAULT)
}

fun decrypt(encryptedtext: String?, key: String): String {
  val KeyData = key.toByteArray()
  val KS = SecretKeySpec(KeyData, "Blowfish")
  val ecryptedtexttobytes = Base64.decode(encryptedtext!!.toByteArray(Charsets.UTF_8), Base64.DEFAULT)
  val cipher = Cipher.getInstance("Blowfish")
  cipher.init(Cipher.DECRYPT_MODE, KS)
  val decrypted = cipher.doFinal(ecryptedtexttobytes)
  return String(decrypted, Charset.forName("UTF-8"))
}

Генератор 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,16)
val text = "Моё сообщение"
// Для шифрования
val encrypt_text = encrypt(text, key)
//encrypt_text = "Абракадабра"

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

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

13 + 8 =