logo
ОЗІ / Лекц_ї / все / Методы и средства защиты информации, 2003

Стандарт криптографического преобразования данных гост 28147-89

Стандарт криптографического преобразования данных ГОСТ 28147-89 рекомендован к использованию для защиты любых данных, представленных в виде двоичного кода. Данный стандарт формировался с учетом мирового опыта, и в частности, при его разработке были приняты во внимание недостатки алгоритма DES. Стандарт довольно сложен, поэтому приведем лишь его концептуальное описание.

Алгоритм криптографического преобразования, установленный ГОСТ 28147-89 (далее — ГОСТ) используется для шифрования данных в двух режимах, а также для выработки имитовставки, которая является средством контроля целостности данных и зависит от ключей. При шифровании алгоритм ГОСТ сводится к шифру гаммирования. Блок гаммы представляет собой 64-битовую комбинацию, состоящую из двух последовательных 32-битовых блоков. Исходя из удобства изложения, далее будем называть любой 64-битовый блоккомбинацией, а также считать, что блок состоит их двух сцепленных подблоков из 32-х битов каждый.

Гамма накладывается поразрядно по модулю 2. Каждая комбинация гаммы представляет собой результат шифрпреобразования с помощью шифра простой замены на множестве 64-битовых комбинаций. Входные комбинации для указанного шифра, в общем случае, формируются в зависимости от ключей, псевдослучайного открытого параметра S(синхропосылка), известных константс1,c2и предыдущего блока шифртекста. Фактически задача каждого из режимов шифрования — это формирование 64-битовых комбинаций для входа в основной режим работы ГОСТ, называемыйрежимом простой замены. По сути, ключи необходимы для работы ГОСТ именно в этом режиме. Комбинация гаммы является результатом работы алгоритма в режиме простой замены.

Алгоритм ГОСТ в качестве исходных данных использует три параметра: K, XиZ64-битовый блок данных. Первый параметр являетсядолговременным, а второй —сеансовымключом.

Параметры независимы и имеют размер 512, 256 и 64 бита соответственно. K представляет собой отображение множества блоков в себя. Это отображение реализует потетрадную замену 32-разрядных блоков в 32-х разрядные и состоит из 8 подключей. Подключ Ki (i = 1, …, 8), входящий в K, является таблицей замены для i-той (слева) тетрады, т.е. состоит из 16 тетрад. В стандарте ключ K называется блоком подстановки, а подключи Kузлами замены.

Сеансовый ключ Xсостоит из восьми 32-разрядных подключейXi, каждый из которых в соответствующий момент используется для суммирования с некоторым блоком по модулю 2. Режим простой замены алгоритма ГОСТ реализован в виде шифра Файстеля.

Шифрование блока открытого текста Zалгоритмом ГОСТ производится за 32 цикла. На каждом цикле происходит преобразование входной комбинации в выходную. Шифртекстом является результат работы (выход) тридцать второго цикла, подвергнутый очень простому дополнительному преобразованию.

Процесс шифрования в режиме простой замены (рис. , который обозначим через T = ГОСТ(S)можно представить в виде последовательности 34 блоковu = (U–2, U–1, U0, U1, U2, …, U30, U31), где U-1||U0 = S и U31||U30 = T.

Здесь U-1||U0 — результат работы цикла0,U0||U1 — результат работы цикла1и т.д. доU31||U30— результата работы цикла31. Дополнительное преобразование меняет порядок следования блоков:U31||U30= T.

На цикле iиспользуется подключXt(i). При шифровании используется следующая последовательность выбора подключей от начального и до последнего цикла:

t(i) = {0,1,2,3,4,5,6,7; 0,1,2,3,4,5,6,7; 0,1,2,3,4,5,6,7; 7,6,5,4,3,2,1,0}

При расшифровывании используется обратный порядок следования подключей.

В режиме гаммирования последовательность 64-битовых комбинаций гаммы имеет вид: γK = ГОСТ(φ(σK–1)),k = 1, 2, ..., гдеσ0 = ГОСТ(S). При этом дляs1||s2φ(σ)состоит из двух блоков:s1 º c1, s2 + c2.Здесь сложение сc2 производится по mod 232, а s1 º c1 = s1 + c1 mod(232 – 1) за исключением случая s1 º c1, s2 + c2, когда результат принимается равным232 – 1. Шестнадцатеричное представлениеc1иc2, соответственно, следующее:х01010101их01010104,

В режиме гаммирования с обратной связью

γ1 = ГОСТ(S),γk+1 = ГОСТ(γk tk),k = 1, 2, …, t— комбинация открытого текста.

Рис. 18.9.Цикл шифрования в режиме простой замены

Пример реализации алгоритма ГОСТ представлен в листингах 18.5 и 18.6 (компилятор — MicrosoftVisualC6.0).

Листинг 18.5.Пример реализации алгоритма ГОСТ на языкеC++ в виде библиотечного класса (библиотекаCrypto++ 5.1)

#include "pch.h" #include "gost.h" #include "misc.h"

Продолжение листинга 18.5

NAMESPACE_BEGIN(CryptoPP) // S-блоки const byte GOST::Base::sBox[8][16]={ {4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3}, {14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9}, {5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11}, {7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3}, {6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2}, {4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14}, {13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12}, {1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12}}; bool GOST::Base::sTableCalculated = false; word32 GOST::Base::sTable[4][256]; void GOST::Base::UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length) { AssertValidKeyLength(length); PrecalculateSTable(); GetUserKey(LITTLE_ENDIAN_ORDER, key.begin(), 8, userKey, KEYLENGTH); } void GOST::Base::PrecalculateSTable() { if (!sTableCalculated) { for (unsigned i = 0; i < 4; i++) for (unsigned j = 0; j < 256; j++) { word32 temp = sBox[2*i][j%16] | (sBox[2*i+1][j/16] << 4); sTable[i][j] = rotlMod(temp, 11+8*i); } sTableCalculated=true; } } #define f(x) ( t=x, \ sTable[3][GETBYTE(t, 3)] ^ sTable[2][GETBYTE(t, 2)] \

Продолжение листинга 18.5

^ sTable[1][GETBYTE(t, 1)] ^ sTable[0][GETBYTE(t, 0)] ) typedef BlockGetAndPut<word32, LittleEndian> Block; void GOST::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const { word32 n1, n2, t; Block::Get(inBlock)(n1)(n2); for (unsigned int i=0; i<3; i++) { n2 ^= f(n1+key[0]); n1 ^= f(n2+key[1]); n2 ^= f(n1+key[2]); n1 ^= f(n2+key[3]); n2 ^= f(n1+key[4]); n1 ^= f(n2+key[5]); n2 ^= f(n1+key[6]); n1 ^= f(n2+key[7]); } n2 ^= f(n1+key[7]); n1 ^= f(n2+key[6]); n2 ^= f(n1+key[5]); n1 ^= f(n2+key[4]); n2 ^= f(n1+key[3]); n1 ^= f(n2+key[2]); n2 ^= f(n1+key[1]); n1 ^= f(n2+key[0]); Block::Put(xorBlock, outBlock)(n2)(n1); } void GOST::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const { word32 n1, n2, t; Block::Get(inBlock)(n1)(n2);

Окончание листинга 18.5

n2 ^= f(n1+key[0]); n1 ^= f(n2+key[1]); n2 ^= f(n1+key[2]); n1 ^= f(n2+key[3]); n2 ^= f(n1+key[4]); n1 ^= f(n2+key[5]); n2 ^= f(n1+key[6]); n1 ^= f(n2+key[7]); for (unsigned int i=0; i<3; i++) { n2 ^= f(n1+key[7]); n1 ^= f(n2+key[6]); n2 ^= f(n1+key[5]); n1 ^= f(n2+key[4]); n2 ^= f(n1+key[3]); n1 ^= f(n2+key[2]); n2 ^= f(n1+key[1]); n1 ^= f(n2+key[0]); } Block::Put(xorBlock, outBlock)(n2)(n1); } NAMESPACE_END

Листинг 18.6.Заголовочный файлgost.h, используемый при реализации алгоритма ГОСТ на языкеC++ в виде библиотечного класса (библиотекаCrypto++ 5.1)

#ifndef CRYPTOPP_GOST_H #define CRYPTOPP_GOST_H #include "seckey.h" #include "secblock.h" NAMESPACE_BEGIN(CryptoPP) struct GOST_Info : public FixedBlockSize<8>, public FixedKeyLength<32> { static const char *StaticAlgorithmName() {return "GOST";}};

Окончание листинга 18.6

{ class Base : public BlockCipherBaseTemplate<GOST_Info> { public: void UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length); protected: static void PrecalculateSTable(); static const byte sBox[8][16]; static bool sTableCalculated; static word32 sTable[4][256]; FixedSizeSecBlock<word32, 8> key; }; class Enc : public Base { public: void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; }; class Dec : public Base { public: void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; }; public: typedef BlockCipherTemplate<ENCRYPTION, Enc> Encryption; typedef BlockCipherTemplate<DECRYPTION, Dec> Decryption; }; typedef GOST::Encryption GOSTEncryption; typedef GOST::Decryption GOSTDecryption; NAMESPACE_END #endif