Статус: Новичок
Группы: Участники
Зарегистрирован: 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 ?
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 09.10.2008(UTC) Сообщений: 181
|
SV неявно содержится в wrappedKey, поэтому дополнительно передавать ничего не надо.
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 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)
| Причина: Не указана
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 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);
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 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)
| Причина: Не указана
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 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 действительно не доступен. |
С уважением, Александр. |
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 08.12.2010(UTC) Сообщений: 6
|
Цитата:Форматы передаваемой информации в этих примерах в Java и C# не совпадают, в C# формат ближе к формату XML encrypt в Java к CMS. Поскольку классы перекодирования wrappedKey к единому формату недоступны, видимо, придется использовать CMS. Спасибо - все стало понятно.
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 24.12.2007(UTC) Сообщений: 390  Откуда: КриптоПро Поблагодарили: 2 раз в 2 постах
|
Цитата:Поскольку классы перекодирования wrappedKey к единому формату недоступны, видимо, придется использовать CMS. Спасибо - все стало понятно. Класс CryptoPro.Sharpei.GostWrappedKey - доступен, он public. GostWrappedKeyObject - internal, он Вам и не нужен. |
С уважением, Александр. |
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close