Стандарты симметричного шифрования стран СНГ на Python
Первые недели нового года самое подходящее время для того, чтобы уютно устроившись у окошка, вспомнить что же нам принес год ушедший.
А принес он нам два новых стандарта шифрования. Российский стандарт ГОСТ Р 34.12–2015 (блочный шифр Кузнечик). И украинский ДСТУ 7624:2014 (блочный шифр Калина). Холодными, зимними вечерами нельзя упускать такой удачный повод покодить. Под катом краткое описание алгоритмов и их реализация на Python. А чтобы новым шифрам было веселее, разбавим их общество белорусским СТБ 34.101.31–2007.
ГОСТ Р 34.12–2015
Начать предлагаю с российского стандарта — блочного шифра Кузнечик. Длина входного блока шифра — 128 бит, длина ключа — 256 бит.
В шифре используются следующие преобразования:
Процедуру зашифрования 128-битного блока a формально описывается выражением:
.
Что в более наглядной форме выглядит так:
Раундовые 128-битные ключи K1, K2 получаются разбиением основного 256-битного ключа пополам.
С их помощью вычисляются следующие раундовые ключи:
При расшифровании используются обратные преобразования:
Пример использования на Python:
if __name__ == '__main__':
mtest = list(binascii.unhexlify('1122334455667700ffeeddccbbaa9988'))
ktest = list(binascii.unhexlify('8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef'))
gost =gost2015(ktest)
print('GOST 34.12-2015')
print(datetime.datetime.now())
c = gost.encryption(mtest)
d = gost.decryption(c)
print(datetime.datetime.now())
ДСТУ 7624:2014
Введенный в июле 2015 года в качестве украинского стандарта шифр Калина поддерживает несколько вариантов длины блока и ключа. Здесь я опишу версию шифра с длиной блока и длиной ключа равной 128 бит.
Внутреннее состояние шифра является матрицей с 8 рядами и 2 столбцами. Перед началом шифрования матрица заполняется байтами открытого текста. Затем над элементами матрицы производится 10 раундов следующих преобразований.
Процесс шифрования описывается следующим выражением:
Или в более наглядном виде:
Для формирования раундовых ключей сначала, используя мастер-ключ К, вычисляется промежуточный ключ :
, где для случаев, когда длина блока равна длине ключа.
Ключи для четных раундов генерируются на основе промежуточного ключа:
, где i — номер раунда, а и 0×01000100010001000100010001000100
Ключи для нечетных раундов вычисляются так:
, где l — длина блока.
При расшифровании используются обратные преобразования:
Пример использования на Python:
if __name__ == '__main__':
key = list(binascii.unhexlify('000102030405060708090a0b0c0d0e0f'))
pt = list(binascii.unhexlify('101112131415161718191a1b1c1d1e1f'))
dstu =dstu2014(key)
key2 = list(binascii.unhexlify('0f0e0d0c0b0a09080706050403020100'))
ct = list(binascii.unhexlify('1f1e1d1c1b1a19181716151413121110'))
dstu2 = dstu2014(key2)
print(datetime.datetime.now())
c = dstu.encryption(pt)
d = dstu2.decryption(ct)
print(datetime.datetime.now())
СТБ 34.101.31–2007
Шифр BelT, имеющий длину блока 128 бит и длину ключа 256 бит, был принят в качестве стандарта симметричного шифрования республики Беларусь в 2011 году. Шифрование осуществляется 8 раундами преобразований, применяемых ко входному блоку.
Процедура зашифрования состоит из следующих шагов:
При расшифровании те же операции применяются в обратном порядке.
Пример использования на Python:
if __name__ == '__main__':
key = list(binascii.unhexlify('E9DEE72C8F0C0FA62DDB49F46F73964706075316ED247A3739CBA38303A98BF6'))
belt1 = belt(key)
m = list(binascii.unhexlify('B194BAC80A08F53B366D008E584A5DE4'))
key2 = list(binascii.unhexlify('92BD9B1CE5D141015445FBC95E4D0EF2682080AA227D642F2687F93490405511'))
belt2 = belt(key2)
c = list(binascii.unhexlify('E12BDC1AE28257EC703FCCF095EE8DF1'))
print(datetime.datetime.now())
c1 = belt1.encryption(m)
d1 = belt2.decryption(c)
print(datetime.datetime.now())
PS
Реализацию всех описанных алгоритмов на Python можно найти на GitHub.
Ссылки
- Более подробное описание шифра Кузнечик приводится и в этой статье пользователя ru_crypt, из которой я позаимствовал несколько иллюстраций.
- Текст стандарта ГОСТ Р 34.12–2015 можно найти тут.
- Описание шифра Калина доступно здесь.
- Стандарт СТБ 34.101.31–2007 лежит тут.