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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline slider78  
#1 Оставлено : 18 декабря 2020 г. 8:05:36(UTC)
slider78

Статус: Участник

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

Здравствуйте

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


public static byte [] encrypt (final byte[] data, final X509Certificate publicCert) throws GeneralSecurityException, Asn1Exception
{
Cipher cipher = Cipher.getInstance("GOST28147/CFB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, publicCert);
return cipher.doFinal(buffer);
}

получаю ошибку

Caused by: java.lang.ClassCastException: class ru.CryptoPro.JCP.Key.GostPublicKey cannot be cast to class ru.CryptoPro.JCSP.Key.GostSecretKey (ru.CryptoPro.JCP.Key.GostPublicKey and ru.CryptoPro.JCSP.Key.GostSecretKey are in unnamed module of loader 'app')
at ru.CryptoPro.JCSP.Cipher.GostCipher.prepare(Unknown Source)
at ru.CryptoPro.JCSP.Cipher.GostCipher.engineDoFinal(Unknown Source)
at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2202)

в примерах не нашел ни один подходящий для моего случая

пример сертификата

подскажите, пожалуйста, правильный способ шифрования, если этот не подходит

спасибо
Offline Евгений Афанасьев  
#2 Оставлено : 18 декабря 2020 г. 9:39:02(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 21 раз
Поблагодарили: 715 раз в 675 постах
Здравствуйте. Скорее всего, у вас провайдер по умолчанию выставлен jcsp (в настройках панели, в Алгоритмах, или в java.security провайдер jcsp выше jcp, или программно мы поместили jcsp над jcp), отличный от того, что вы в коде используете. В cipher.getInstance вы имя провайдера не указали, то есть берётся имя по умолчанию, а publicCert прочитан, скорее всего, с помощью другого провайдера, например, jcp.
Нужно использовать строго один провайдер - либо jcp, либо jcsp.
Кроме того, для этого алгоритма нужен сессионный ключ SecretKey, а не открытый.

Отредактировано пользователем 18 декабря 2020 г. 9:41:02(UTC)  | Причина: Не указана

Offline slider78  
#3 Оставлено : 18 декабря 2020 г. 17:25:47(UTC)
slider78

Статус: Участник

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

спасибо, попробую, но может я не тот алгоритм использую ?
я в этих вопросах, пока плаваю, только начинаю разбираться..
разве вышеупомянутого сертификата из файла не достаточно чтобы просто зашифровать данные ?
какие алгоритмы шифрования допустимы для данного сертификата ? как это можно узнать ?
если нужен сессионный ключ SecretKey, то как его получить ?
может есть у вас какой-то рабочий пример для шифрования при помощи одного только открытого ключа ?
спасибо
Offline Евгений Афанасьев  
#4 Оставлено : 18 декабря 2020 г. 17:47:18(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 21 раз
Поблагодарили: 715 раз в 675 постах
Примеры с шифрованием есть в samples-sources.jar: в пакете userSamples для JCP или в пакете JCSP для JCSP. "Шифрование" может быть разным, популярные сценарии:
* с помощью созданного сессионного ключа на каком-то подходящем алгоритме шифруется некий объем данных, например, для хранения
* зашифровать сообщение (подпись) в адрес некоего получателя
Какой из этих вариантов ваш (зависит от ТЗ)?
Вероятно, второй - зашифровать нечто в адрес получателя, тогда наиболее короткий вариант - использовать EnvelopedSignature из CAdES.jar, примеры в пакете CAdES/enveloped архива samples-sources.jar, например:
Код:

// Зашифрование на вашей стороне в адрес получателя recipientCertificate на его сертификате:
ByteArrayOutputStream envelopedByteArrayOutStream = new ByteArrayOutputStream();
EnvelopedSignature signature = new EnvelopedSignature();
if (transport) { // <-- ключ получателя должен быть ключом подписи и обмена 
  signature.addKeyTransRecipient(recipientCertificate);
} // if
else {
  signature.addKeyAgreeRecipient(recipientCertificate);
} // else
signature.open(envelopedByteArrayOutStream);
signature.update(данные);
signature.close();
byte[] enveloped = envelopedByteArrayOutStream.toByteArray(); // <-- зашифрованное сообщение

Код:

// Расшифрование enveloped на стороне получателя с помощью его закрытого ключа
ByteArrayOutputStream decryptedByteDataStream = new ByteArrayOutputStream();
EnvelopedSignature signature = new EnvelopedSignature(new ByteArrayInputStream(enveloped));
signature.decrypt(recipientCertificate, recipientPrivateKey, decryptedByteDataStream);
данные = decryptedByteDataStream.toByteArray();

Плюс если вы предполагаете использовать провайдер JCSP, а не JCP, то надо сделать его провайдером по умолчанию (в панели JCP на вкладке "Алгоритмы") и указать его перед шифрованием:
Код:

AdESConfig.setDefaultProvider(JCSP.PROVIDER_NAME); // см. рук-во разработчика JCSP

Offline slider78  
#5 Оставлено : 24 декабря 2020 г. 9:40:12(UTC)
slider78

Статус: Участник

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

Спасибо
да, при помощи вашего кода шифрует с участием лишь одного сертификата, но принимающая сторона не может это расшифровать
подскажите, пожалуйста, какие я должен вопросы задать их службе поддержки, чтобы мне потом можно было понять каким, способом мне необходимо шифровать...
и чем отличается шифрование провайдером JCSP от JCP ?
у них тоже нужно спросить, при помощи какого провайдера расшифровывают ?
Offline Евгений Афанасьев  
#6 Оставлено : 24 декабря 2020 г. 10:53:24(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 21 раз
Поблагодарили: 715 раз в 675 постах
Автор: slider78 Перейти к цитате

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

На стороне получателя должно быть ПО вроде КриптоАрм (или иное для расшифрования enveloped data) и установленный сертификат с закрытым ключом получателя. Вообще, изначально у вас должно быть техническое задание:
какими средствами шифровать (какой провайдер, какой язык программирования), в каком формате (enveloped data и др.), на каких ключах (ГОСТ?), какие входные данные, как протестировать полученный результат (доступ к тестовому контуру), образцы/примеры сообщений и др.
Так как вы сообщили мало сведений, было предложено одно из популярных решений.
Автор: slider78 Перейти к цитате

и чем отличается шифрование провайдером JCSP от JCP ?

Почти ничем, разница лишь в том, что JCP - самостоятельный java-провайдер (со своей лицензией), а Java CSP (со своей лицензией) - провайдер, требующий наличия CSP, т.к. использует его. Между собой JCP и JCSP совместимы, один из них должен быть провайдером по умолчанию. Подробности в документации.
Автор: slider78 Перейти к цитате

у них тоже нужно спросить, при помощи какого провайдера расшифровывают ?

Можно попробовать через КриптоАрм с помощью установленного сертификата получателя с его закрытым ключом. Или csptest от КриптоПро CSP.

Отредактировано пользователем 24 декабря 2020 г. 11:02:18(UTC)  | Причина: Не указана

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