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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline refrefref  
#1 Оставлено : 8 декабря 2010 г. 21:06:38(UTC)
refrefref

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

Группы: Участники
Зарегистрирован: 08.12.2010(UTC)
Сообщений: 6

Доброе время суток.

Имеется код примера шифрования/дешифрования по алгоритмам ГОСТ на основе симметричного ключа на C# (class gEncryptFileEphem):

Шифрование:
Код:
// Создаем случайный симметричный ключ.
            Gost28147 symmetric = Gost28147.Create();

            // Создаем случайный ключ отправителя.
            Gost3410 srcContainer = Gost3410.Create();
            Gost3410Parameters srcPublicKeyParameters = srcContainer.ExportParameters(false);

            // Создаем agree ключ
            GostSharedSecretAlgorithm agree = srcContainer.CreateAgree(alg.ExportParameters(false));

            // Зашифровываем симметричный ключ на agree ключе.
            byte[] WrappedKey = agree.Wrap(symmetric, GostKeyWrapMethod.CryptoProKeyWrap);

            // Создаем поток шифратора.
            ICryptoTransform transform = symmetric.CreateEncryptor();
            // Создаем зашифрованный файл.
            using (FileStream ofs = new FileStream(EncryptedFileName, FileMode.Create))
            {
                BinaryWriter bw = new BinaryWriter(ofs);

                // Записываем зашифрованный симметричный ключ.
                bw.Write(WrappedKey.Length);
                bw.Write(WrappedKey);

                // Записываем синхропосылку
                bw.Write(symmetric.IV.Length);
                bw.Write(symmetric.IV);
            }


Для дешифратора необходимо знать: зашифрованный текст, зашифрованный симметричный ключ, синхропосылку (IV), открытый ключ/сертификат шифратора.


Стоит задача написания кода шифратора/дешифратора по тому же алгоритму, но с использованием JCP. В примере SessionEncrypt.java видим следующее:

Код:
/* Генерирование начальной синхропосылки для выработки ключа согласования*/
    final byte[] sv = new byte[RND_LENGTH];
    final SecureRandom random = SecureRandom.getInstance(Constants.RANDOM_ALG);
    random.nextBytes(sv);
    final IvParameterSpec ivspec = new IvParameterSpec(sv);

    /* Выработка ключа согласования алисы c SV*/
    final KeyAgreement alisaKeyAgree =
            KeyAgreement.getInstance(Constants.EXCH_KEY_PAIR_ALG);
    alisaKeyAgree.init(alisaPair.getPrivate(), ivspec, null);
    alisaKeyAgree.doPhase(bobCert.getPublicKey(), true);
    final SecretKey alisaAgree =
            alisaKeyAgree.generateSecret(Constants.CHIPHER_ALG);

    /* Генерирование симметричного ключа алисой с параметрами шифрования из контрольной панели*/
    final KeyGenerator keyGen = KeyGenerator.getInstance(Constants.CHIPHER_ALG);
    final SecretKey simm = keyGen.generateKey();

    /* Зашифрование текста на симметричном ключе алисы*/
    Cipher cipher = Cipher.getInstance(CIPHER_ALG);
    cipher.init(Cipher.ENCRYPT_MODE, simm);
    // передача вектора инициализации бобу
    final byte[] iv = cipher.getIV();
    final byte[] encryptedtext = cipher.doFinal(data, 0, data.length);

    /*Зашифрование симметричного ключа на ключе согласования алисы*/
    cipher.init(Cipher.WRAP_MODE, alisaAgree);
    final byte[] wrappedKey = cipher.wrap(simm);



В этом случае дешифратору необходимо знать: зашифрованный текст, зашифрованный симметричный ключ (wrappedKey), синхропосылку (IV), открытый ключ/сертификат шифратора и вектор инициализации (SV).
Таким образом, появляется еще один дополнительный параметр (SV), который требуется дешифратору.

Нужно ли передавать этот параметр в открытом виде вместе с сообщением, или же он заранее должен быть определен и известен шифратору и дешифратору?
Каким должно быть его значение, чтобы шифратор и дешифратор работали вместе корректно, когда один из них написан на C# по примеру gEncryptFileEphem, а другой на JAVA, по примеру SessionEncrypt ?
Offline Iva  
#2 Оставлено : 9 декабря 2010 г. 16:49:23(UTC)
Iva

Статус: Активный участник

Группы: Участники
Зарегистрирован: 09.10.2008(UTC)
Сообщений: 181

SV неявно содержится в wrappedKey, поэтому дополнительно передавать ничего не надо.
Offline refrefref  
#3 Оставлено : 9 декабря 2010 г. 23:38:00(UTC)
refrefref

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

Группы: Участники
Зарегистрирован: 08.12.2010(UTC)
Сообщений: 6

Код:
 

/* Выработка ключа согласования боба с тем же SV. */
final KeyAgreement bobKeyAgree =
        KeyAgreement.getInstance(Constants.EXCH_KEY_PAIR_ALG);
bobKeyAgree.init(bobPair.getPrivate(), ivspec, null);
bobKeyAgree.doPhase(alisaCert.getPublicKey(), true);
final SecretKey bobAgree =
        bobKeyAgree.generateSecret(Constants.CHIPHER_ALG);


согласно примеру, для расшифровки сообщения (а точнее для получения Бобом ключа согласования), необходимо знать ivspec, который явно хранит в себе SV.
В строке
Код:
bobKeyAgree.init(bobPair.getPrivate(), ivspec, null);
вместо ivspec подставляя следующие значения, получаю различные exception'ы:

null -> java.security.InvalidAlgorithmParameterException: Инициализация должна производиться с вектором синхронизации
new IvParameterSpec(null) -> java.lang.NullPointerException
new IvParameterSpec(new byte[RND_LENGTH]) -> java.security.InvalidKeyException: Wrapped key is invalid (на строке cipher.unwrap(...) )
bobKeyAgree.init без IvParameterSpec -> java.security.InvalidKeyException: Инициализация должна производиться с вектором синхронизации
new IvParameterSpec(SV2), где SV2 отличается от SV -> java.security.InvalidKeyException: Wrapped key is invalid

Если на стороне шифратора (Алисы) массив SV (а следовательно и ivspec) заполняется случайным образом, то как дешифратору (Бобу) проинициализировать bobKeyAgree, не зная его?

Отредактировано пользователем 9 декабря 2010 г. 23:39:15(UTC)  | Причина: Не указана

Offline Iva  
#4 Оставлено : 10 декабря 2010 г. 15:35:50(UTC)
Iva

Статус: Активный участник

Группы: Участники
Зарегистрирован: 09.10.2008(UTC)
Сообщений: 181

Структуры wrappedKey на java и C# разные, придется перекодировать.
На Java есть класс
ru.CryptoPro.JCP.ASN.Gost28147_89_EncryptionSyntax.Gost28147_89_EncryptedKey;
Поля
public Gost28147_89_Key encryptedKey; // собственно зашифрованный ключ
public Gost28147_89_Key maskKey; // optional не использовать
public Gost28147_89_MAC macKey; // имотовставка на ключ
Закодировать можно так
Код:
        Asn1BerEncodeBuffer buf = new Asn1BerEncodeBuffer();
        encryptedKey.encode(buf);
        byte[] wrappedKey = buf.getMsgCopy();

Раскодирование
Код:
        Asn1BerDecodeBuffer buf1 = new Asn1BerDecodeBuffer(wrappedKey);
        encryptedKey.decode(buf1);

Для работы с wrappedKey на C# есть struct GostWrappedKey.
Поля
public byte[] Mac; // имотовставка на ключ
public byte[] Ukm; // та самая SV из-за которой и вопрос
public string EncryptionParamSet;
public byte[] EncryptedKey; // собственно зашифрованный ключ
Есть декодирующий метод SetByXmlWrappedKey
Код:
            GostWrappedKeyObject gwk = new GostWrappedKeyObject();
            gwk.SetByXmlWrappedKey(wrapped);
Offline refrefref  
#5 Оставлено : 11 декабря 2010 г. 4:28:04(UTC)
refrefref

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

Группы: Участники
Зарегистрирован: 08.12.2010(UTC)
Сообщений: 6

Iva, спасибо за ответы! Кажется, что-то начинает проясняться.

Если я правильно понял, то приведеный выше код обеспечивает
совместимость wrappedKey между Java и С# приложениями. Но не
освобождает от необходимости передачи Бобу значения SV,
так как в коде Java он нужен для расшифровки переданного wrappedKey.

После изучения материалов форума и примеров, выяснил, что
код приведенный Вами выше, используется для работы с cms-сообщениями.
Отсюда я делаю вывод, что примеры samples_src.jar\userSamples\SessionEncrypt.java
и simple.zip\Encrypt\gEncryptFileEphem.cs хоть и делают одно и то же (на разных платформах),
но между собой не совместимы. А для взаимного обмена зашифрованными сообщениями (по ключу
согласования на основе симметричного ключа
) между C# и Java, нужно обязательно
использовать cms - верно?

Не могли бы Вы подсказать, какие из примеров для C# и Java могут
обмениваться между собой зашифрованными сообщениями по упомянутому выше алгоритму?
Большое спасибо!

---- добавлено:
Пытался использовать Ваш код в C#:
Цитата:
Ошибка 1 "CryptoPro.Sharpei.GostWrappedKeyObject" недоступен из-за его уровня защиты

Отредактировано пользователем 11 декабря 2010 г. 23:01:09(UTC)  | Причина: Не указана

Offline Челпанов А.  
#6 Оставлено : 13 декабря 2010 г. 12:41:48(UTC)
Челпанов А.

Статус: Активный участник

Группы: Участники
Зарегистрирован: 24.12.2007(UTC)
Сообщений: 390
Мужчина
Откуда: КриптоПро

Поблагодарили: 2 раз в 2 постах
Цитата:
Если я правильно понял, то приведеный выше код обеспечивает
совместимость wrappedKey между Java и С# приложениями. Но не
освобождает от необходимости передачи Бобу значения SV,
так как в коде Java он нужен для расшифровки переданного wrappedKey.
Да. В примерах на Java "передаестся" SV и EncryptedKey в виде двух отдельных байтовых массивов, в примере на C# в виде одного массива, но содержит он те же SV и EncryptedKey.
Цитата:
После изучения материалов форума и примеров, выяснил, что
код приведенный Вами выше, используется для работы с cms-сообщениями.
Отсюда я делаю вывод, что примеры samples_src.jar\userSamples\SessionEncrypt.java
и simple.zip\Encrypt\gEncryptFileEphem.cs хоть и делают одно и то же (на разных платформах),
но между собой не совместимы. А для взаимного обмена зашифрованными сообщениями (по ключу
согласования на основе симметричного ключа) между C# и Java, нужно обязательно
использовать cms - верно?
Оба примера (C# и Java) используют свой нестандартизованный формат; они и являются примерами для передачи сообщений в удобном Вам формате. Форматы передаваемой информации в этих примерах в Java и C# не совпадают, в C# формат ближе к формату XML encrypt в Java к CMS.
Цитата:
Не могли бы Вы подсказать, какие из примеров для C# и Java могут
обмениваться между собой зашифрованными сообщениями по упомянутому выше алгоритму?

Для передачи сообщений можно использовать CMS и XML (signed, encrypted), совеместимость по этим форматам проверена. Примеры есть в обоих SDK (в Sharpei: Simple.zip/CMS).
Цитата:
Пытался использовать Ваш код в C#...

public класс CryptoPro.Sharpei.GostWrappedKey. GostWrappedKeyObject действительно не доступен.
С уважением, Александр.
Offline refrefref  
#7 Оставлено : 13 декабря 2010 г. 15:00:23(UTC)
refrefref

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

Группы: Участники
Зарегистрирован: 08.12.2010(UTC)
Сообщений: 6

Цитата:
Форматы передаваемой информации в этих примерах в Java и C# не совпадают, в C# формат ближе к формату XML encrypt в Java к CMS.


Поскольку классы перекодирования wrappedKey к единому формату недоступны, видимо, придется использовать CMS.
Спасибо - все стало понятно.
Offline Челпанов А.  
#8 Оставлено : 13 декабря 2010 г. 15:58:02(UTC)
Челпанов А.

Статус: Активный участник

Группы: Участники
Зарегистрирован: 24.12.2007(UTC)
Сообщений: 390
Мужчина
Откуда: КриптоПро

Поблагодарили: 2 раз в 2 постах
Цитата:
Поскольку классы перекодирования wrappedKey к единому формату недоступны, видимо, придется использовать CMS.
Спасибо - все стало понятно.
Класс CryptoPro.Sharpei.GostWrappedKey - доступен, он public. GostWrappedKeyObject - internal, он Вам и не нужен.
С уважением, Александр.
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.