Ошибка здесь заключается в прямом использовании криптографического алгоритма, без указания конкретного протокола и номера версии протокола, который поставляется вместе с ним.К счастью, есть способы выйти из этого, и указывает конкретный протокол .
Один из приемов, используемых криптографией, заключается в том, что невозможно генерировать конкретный контент случайным образом просто потому, чтогенерации конкретного значения уменьшается на каждый бит.Так что вы можете сделать префикс вашего зашифрованного текста, например, с битным значением 128/16.Вероятность того, что вы сгенерируете это значение в начале своего зашифрованного текста, равна 2 степени 128 для каждого сообщения (меньше, если сообщения не являются случайными для конкретного ключа).Другими словами, вероятность не меньше, чем угадывание ключа AES-128;мы называем такой шанс "незначительным".Этот трюк, конечно, зависит от вывода шифрования ECB с использованием случайного ключа, который также должен быть случайным.
Однако в будущем вы можете захотеть включить один или несколько байтов в качестве индикатора версии протокола .Таким образом, вы можете отправить, например, значение байта 01
в качестве новой версии, а затем 16-байтовое магическое значение , за которым следует случайный одноразовый номер для GCM, зашифрованный текст и тег аутентификации GCM (если он еще не включен)в зашифрованном тексте GCM).После того, как вы избавились от версии протокола ECB (версия 00
, не указанная в ваших сообщениях), вы можете избавиться от магии и повторно использовать 16 байтов в заголовке протокола ваших сообщений для протокола 2 или выше..
Если вы хотите создать красивую магию, вы можете использовать любой вид 16-байтовой строки, скажем, "Protocol 1, GCM:"
(без кавычек) в ASCII.Вы также можете использовать крайние левые 128 битов хэша, если хотите использовать строку большего размера.
Итак, изначально ваша логика будет в псевдокоде:
versionByte = message[0]
if message.length >= 17 && versionByte == 01h then
magic = message[1- 16]
if magic == "Protocol 1, GCM:" then
gcmDecrypt(message, 17)
else
ecbDecrypt(message, 0)
// --- include other versions here ---
else
ecbDecrypt(message, 0)
Конечно, этовсе еще очень простой протокол.Но, по крайней мере, вы можете изменить это позже.Возможно, вы захотите взглянуть на более полные спецификации протокола, такие как Fernet, CMS или - конечно же - TLS, а не только на AES-GCM.
Что бы вы ни делали: запишите свой протокол в отдельный документ и обратитесь к нему из своего кода .Вы можете указать свой простой протокол в исходном коде как легкий поиск.