Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline Igor P  
#1 Оставлено : 22 февраля 2018 г. 3:35:14(UTC)
Igor P

Статус: Новичок

Группы: Участники
Зарегистрирован: 22.02.2018(UTC)
Сообщений: 3
Российская Федерация

Добрый день!

В реализации КриптоПро JCP 2.0.39014 и 2.0.39442 имеется расхождение с документацией в инициализации шифратора GOST28147.

В соответствии с документацией КриптоПро "ЖТЯИ.00091-01 33 02. Руководство программиста (модули шифрования)", раздел "4.2. Инициализация шифратора и определение его параметров":
Цитата:
во втором способе вызова функции init(int opmode, Key key, AlgorithmParameterSpec params) передаются параметры params, определяющие работу шифратора. В качестве таких параметров в криптопровайдере «КриптоПро JCP» версия 2.0 (модули шифрования) допускается передавать объекты следующих типов: ...GostCipherSpec - этот класс представляет собой набор параметров алгоритма ГОСТ 28147-89, а также вектор инициализации шифратора... Таким образом, объект типа GostCipherSpec, передаваемый в качестве параметров params определяет параметры шифрования (узел замены) и вектор инициализации.
...если параметры алгоритма шифрования (узел замены) заданы (в случае передачи в качестве параметров params объекта интерфейса параметров шифрования ParamsInterface или класса GostCipherSpec), то они и будут использованы в процессе выполнения операции шифрования. В противном случае, параметры шифрования определяются в соответствии с параметрами шифрования передаваемого ключа key;


В действительности, вопреки документации, параметры алгоритма шифрования (узел замены), передаваемые в метод Cipher.init в GostCipherSpec, игнорируются, и вместо них используются параметры алгоритма шифрования (узел замены), заданные в ключе (параметр key метода init).

Где имеет место ошибка - в документации или в реализации?

Исходный код, демонстрирующий описанное поведение:
Цитата:

import java.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

import ru.CryptoPro.Crypto.Key.GostSecretKey;
import ru.CryptoPro.JCP.params.CryptParamsSpec;
import ru.CryptoPro.JCP.params.ParamsInterface;
import ru.CryptoPro.JCP.spec.GostCipherSpec;

public class CipherInitBug {

public static void main(String[] args) throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance ("GOST28147", "Crypto");
ParamsInterface encryptKeyParams = CryptParamsSpec.getInstance(CryptParamsSpec.TC26_A);

keyGenerator.init (encryptKeyParams);

// Для шифрования данных используем ключ с параметрами алгоритма шифрования (узлом замены) TC26_A.
SecretKey encryptKey = keyGenerator.generateKey ();

// Выводит: ru.CryptoPro.JCP.params.CryptParamsSpec: 1.2.643.2.2.31.12
System.out.println("Encryption key params: " + ((GostSecretKey) encryptKey).getSpec().getParams());

byte[] clearText = new byte[2048];
for (int i = 0; i < clearText.length; i++) {
clearText[i] = (byte) (i % 256);
}

Cipher encryptCipher = Cipher.getInstance ("GOST28147/CFB/NoPadding", "Crypto");
encryptCipher.init (Cipher.ENCRYPT_MODE, encryptKey);

byte[] textIV = encryptCipher.getIV ();
byte[] cipherText = encryptCipher.doFinal (clearText, 0, clearText.length);

// Для шифрования ключа используем параметры алгоритма шифрования (узел замены),
// отличные от параметров для шифрования данных, чтобы они были установлены по умолчанию
// в расшифровавнном ключе шифрования данных.
ParamsInterface wrapKeyParams = CryptParamsSpec.getInstance(CryptParamsSpec.TC26_B);

keyGenerator.init (wrapKeyParams);

SecretKey wrapKey = keyGenerator.generateKey ();

Cipher wrapCipher = Cipher.getInstance ("GOST28147/CFB/NoPadding", "Crypto");
wrapCipher.init (Cipher.WRAP_MODE, wrapKey);

byte[] keyIV = wrapCipher.getIV();
byte[] wrappedKey = wrapCipher.wrap(encryptKey);

Cipher unwrapCipher = Cipher.getInstance ("GOST28147/CFB/NoPadding", "Crypto");
unwrapCipher.init (Cipher.UNWRAP_MODE, wrapKey, new IvParameterSpec(keyIV));

// В расшифрованном ключе установлены параметры алгоритма шифрвоания (узел замены) TC26_B.
SecretKey decryptKey = (SecretKey) unwrapCipher.unwrap(wrappedKey, "GOST28147", Cipher.SECRET_KEY);

// Выводит: 1.2.643.2.2.31.13
System.out.println("Unwrapped key params: " + ((GostSecretKey) decryptKey).getSpec().getParams());

// Данные были зашифрованы с параметрами TC26_A, с этими же параметрами будем инициализировать шифратор для дешифровки.
GostCipherSpec decryptSpec = new GostCipherSpec(textIV, encryptKeyParams);

Cipher decryptCipher = Cipher.getInstance ("GOST28147/CFB/NoPadding", "Crypto");

// Вопреки документации "ЖТЯИ.00091-01 33 02. Руководство программиста (модули шифрования)",
// раздел "4.2. Инициализация шифратора и определение его параметров",
// Cipher.init игнорирует параметры алгоритма шифрования (узел замены), передаваемые в GostCipherSpec (TC26_A).
// Вместо них используются параметры алгоритма шифрования из ключа decryptKey (TC26_B).
decryptCipher.init (Cipher.DECRYPT_MODE, decryptKey, decryptSpec);

byte[] decryptedText = decryptCipher.doFinal (cipherText, 0, cipherText.length);

// Выводит: false. Расшифрованные данные не совпадают с зашифрованными,
// т.к. при расшифровке использовался некорректный узел замены.
System.out.println("Are decrypted data the same as the original one? " + Arrays.equals(clearText, decryptedText));

// В качестве обходного решения проблемы зададим нужные параметры алгоритма шифрования непосредственно на ключе.
((GostSecretKey) decryptKey).getSpec().setParams(encryptKeyParams);

// Выводит: ru.CryptoPro.JCP.params.CryptParamsSpec: 1.2.643.2.2.31.12
System.out.println("Adjusted key params: " + ((GostSecretKey) decryptKey).getSpec().getParams());

decryptCipher.init (Cipher.DECRYPT_MODE, decryptKey, decryptSpec);

byte[] decryptedText2 = decryptCipher.doFinal (cipherText, 0, cipherText.length);

// Выводит: true. После задания нужных параметров алгоритма шифрования непосредственно на ключе
// данные расшифровались корректно.
System.out.println("Are decrypted data the same as the original one? " + Arrays.equals(clearText, decryptedText2));
}

}
Offline Евгений Афанасьев  
#2 Оставлено : 22 февраля 2018 г. 9:47:18(UTC)
Евгений Афанасьев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 4,004
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 21 раз
Поблагодарили: 714 раз в 674 постах
Здравствуйте.
Спасибо за информацию, проверим. Ошибка, скорее всего, в коде.
Offline Евгений Афанасьев  
#3 Оставлено : 22 февраля 2018 г. 10:18:54(UTC)
Евгений Афанасьев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 4,004
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 21 раз
Поблагодарили: 714 раз в 674 постах
Попробуйте тут unwrapCipher.init (Cipher.UNWRAP_MODE, wrapKey, new IvParameterSpec(keyIV)); задать узел замены (можно через GostCipherSpec).

Отредактировано пользователем 22 февраля 2018 г. 10:22:37(UTC)  | Причина: Не указана

Offline Igor P  
#4 Оставлено : 22 февраля 2018 г. 10:30:10(UTC)
Igor P

Статус: Новичок

Группы: Участники
Зарегистрирован: 22.02.2018(UTC)
Сообщений: 3
Российская Федерация

Задал:
Цитата:
unwrapCipher.init (Cipher.UNWRAP_MODE, wrapKey, new GostCipherSpec(keyIV, encryptKeyParams));

Результат не поменялся.

Задал так:
Цитата:
unwrapCipher.init (Cipher.UNWRAP_MODE, wrapKey, new GostCipherSpec(keyIV, wrapKeyParams));

Результат тоже не поменялся (тут, по идее, и не должен был поменяться).
Offline Евгений Афанасьев  
#5 Оставлено : 22 февраля 2018 г. 10:36:13(UTC)
Евгений Афанасьев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 4,004
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 21 раз
Поблагодарили: 714 раз в 674 постах
В ближайшее время посмотрю.
Offline Евгений Афанасьев  
#6 Оставлено : 28 февраля 2018 г. 16:14:11(UTC)
Евгений Афанасьев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 4,004
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 21 раз
Поблагодарили: 714 раз в 674 постах
Добрый день.
Ошибку воспроизвели, она присутствует для данных больше 1Кб, в следующей сборке будет устранена (в строке "decryptCipher.init (Cipher.DECRYPT_MODE, decryptKey, decryptSpec)" будут использованы параметры decryptSpec), спасибо за помощь.

Отредактировано пользователем 28 февраля 2018 г. 16:34:47(UTC)  | Причина: Не указана

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