Статус: Новичок
Группы: Участники
Зарегистрирован: 24.10.2025(UTC) Сообщений: 3  Сказал(а) «Спасибо»: 2 раз
|
Здравствуйте, коллеги. Подскажите, пожалуйста, советом. Для подключения к API ЕПГУ при помощи СВОКС есть требование: Цитата: Подписать указанное значение с использованием закрытого ключа ИС организации с использованием алгоритмов ГОСТ Р 34.10-2012 и ГОСТ Р 34.11-2012 в формате PKCS#7 с открепленными данными;
Два вопроса: - решает ли задачу подписания в формате PKCS#7 с открепленными данными команда cryptcp.x64.exe -sign -dn "CN=ООО «....»" -detached -cert -hashalg 1.2.643.7.1.1.2.2 INPUT_FILE.txt INPUT_FILE.sig ? - в каком примере в samples-sources.jar можно подсмотреть реализацию подписания строки в формате PKCS#7 с открепленными данными? Я смотрел на пример ZapretInfoExample.java и пытался сделать по аналогии, но падает на подписании signature.sign(); Код: JCPInit.initProviders(false);
InputStream privateKeyInputStream = SignUtilTest.class.getClassLoader().getResourceAsStream("static/test.pfx");
KeyStore keyStore = KeyStore.getInstance(JCSP.PFX_STORE_NAME, JCSP.PROVIDER_NAME);
keyStore.load(privateKeyInputStream, KEY_PASSWORD.toCharArray());
//Получение всех CN из контейнера
keyStore.aliases().asIterator().forEachRemaining(System.out::println);
// Получение приватного ключа
log.info("Получение приватного ключа...");
PrivateKey privateKey = (PrivateKey) keyStore.getKey(ALIAS, KEY_PASSWORD.toCharArray());
log.info("Приватный ключ успешно получен. Алгоритм приватного ключа: {}", privateKey.getAlgorithm());
X509Certificate certificate = (X509Certificate) keyStore.getCertificate(ALIAS);
final Signature signature = Signature.getInstance(JCP.GOST_SIGN_2012_256_NAME);
signature.initSign(privateKey);
signature.update(INPUT_DATA.getBytes(StandardCharsets.UTF_8));
final byte[] sign = signature.sign();
Алгоритм приватного ключа: GOST3410DH_2012_256 Ошибка выглядит так: Цитата: java.security.SignatureException: Unsupported method.
at ru.CryptoPro.JCSP.Key.AbstractKeySpec.signature(Unknown Source) at ru.CryptoPro.JCP.Sign.cl_0.engineSign(Unknown Source) at java.base/java.security.Signature.sign(Signature.java:713) at ru.sample.sign.util.SignUtilTest.shouldCreatePKCS7(SignUtilTest.java:149) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727) at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
Версия КриптоПро Java CSP 5.0.42119-A Версия BouncyCastle bcprov-jdk15on 1.60 Заранее спасибо.
|
|
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 06.12.2008(UTC) Сообщений: 4,064  Откуда: Крипто-Про Сказал(а) «Спасибо»: 21 раз Поблагодарили: 740 раз в 698 постах
|
Добрый день.
По п.1 нужно сравнить получаемое сообщение с ожидаемым. Скорее всего, будет создана отделенная подпись PKCS7 или CMS на алгоритме ГОСТ 2012 (256).
Скорее всего, у вас провайдер по умолчанию - не JCSP, а JCP. У Signature надо явно указать имя провайдера - JCSP.PROVIDER_NAME. Или задать в панели управления JCP (скрипт ControlPane) провайдер по умолчанию - JCSP. |
|
 1 пользователь поблагодарил Евгений Афанасьев за этот пост.
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 24.10.2025(UTC) Сообщений: 3  Сказал(а) «Спасибо»: 2 раз
|
По пункту 1 - знать бы это ожидаемое... Разработка идет практически вслепую, спросить не у кого. По ошибке: да, Вы правы, ошибка ушла если явно указать провайдер. Формируется и подписывается. Однако, если проверять подпись с помощью cptools, то дает ошибку при проверке (0x80090008: Указан неправильный алгоритм.) Полный код подписания: Код: @Test
void shouldCreatePKCS7() throws KeyStoreException, NoSuchProviderException, CertificateException, IOException, NoSuchAlgorithmException, UnrecoverableKeyException, InvalidKeyException, SignatureException, Asn1Exception {
JCPInit.initProviders(false);
InputStream privateKeyInputStream = SignUtilTest.class.getClassLoader().getResourceAsStream("static/test.pfx");
KeyStore keyStore = KeyStore.getInstance(JCSP.PFX_STORE_NAME, JCSP.PROVIDER_NAME);
keyStore.load(privateKeyInputStream, KEY_PASSWORD.toCharArray());
//Получение всех CN из контейнера
keyStore.aliases().asIterator().forEachRemaining(System.out::println);
// Получение приватного ключа
log.info("Получение приватного ключа...");
PrivateKey privateKey = (PrivateKey) keyStore.getKey(ALIAS, KEY_PASSWORD.toCharArray());
log.info("Приватный ключ успешно получен. Алгоритм приватного ключа: {}", privateKey.getAlgorithm());
X509Certificate certificate = (X509Certificate) keyStore.getCertificate(ALIAS);
final Signature signature = Signature.getInstance(JCP.GOST_SIGN_2012_256_NAME, JCSP.PROVIDER_NAME);
signature.initSign(privateKey);
signature.update(INPUT_DATA.getBytes(StandardCharsets.UTF_8));
final byte[] sign = signature.sign();
// Формируем контекст подписи формата PKCS7.
final ContentInfo all = new ContentInfo();
all.contentType = new Asn1ObjectIdentifier(
new OID(CMStools.STR_CMS_OID_SIGNED).value);
final SignedData cms = new SignedData();
all.content = cms;
cms.version = new CMSVersion(1);
// Идентификатор алгоритма хеширования.
cms.digestAlgorithms = new DigestAlgorithmIdentifiers(1);
final DigestAlgorithmIdentifier a = new DigestAlgorithmIdentifier(
new OID(CMStools.DIGEST_OID).value);
a.parameters = new Asn1Null();
cms.digestAlgorithms.elements[0] = a;
// Т.к. подпись отсоединенная, то содержимое отсутствует.
cms.encapContentInfo = new EncapsulatedContentInfo(
new Asn1ObjectIdentifier(new OID(CMStools.STR_CMS_OID_DATA).value), null);
// Добавляем сертификат подписи.
cms.certificates = new CertificateSet(1);
final ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate asnCertificate =
new ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate();
final Asn1BerDecodeBuffer decodeBuffer =
new Asn1BerDecodeBuffer(certificate.getEncoded());
asnCertificate.decode(decodeBuffer);
cms.certificates.elements = new CertificateChoices[1];
cms.certificates.elements[0] = new CertificateChoices();
cms.certificates.elements[0].set_certificate(asnCertificate);
// Добавляем информацию о подписанте.
cms.signerInfos = new SignerInfos(1);
cms.signerInfos.elements[0] = new SignerInfo();
cms.signerInfos.elements[0].version = new CMSVersion(1);
cms.signerInfos.elements[0].sid = new SignerIdentifier();
final byte[] encodedName = certificate.getIssuerX500Principal().getEncoded();
final Asn1BerDecodeBuffer nameBuf = new Asn1BerDecodeBuffer(encodedName);
final Name name = new Name();
name.decode(nameBuf);
final CertificateSerialNumber num = new CertificateSerialNumber(
certificate.getSerialNumber());
cms.signerInfos.elements[0].sid.set_issuerAndSerialNumber(
new IssuerAndSerialNumber(name, num));
cms.signerInfos.elements[0].digestAlgorithm =
new DigestAlgorithmIdentifier(new OID(CMStools.DIGEST_OID).value);
cms.signerInfos.elements[0].digestAlgorithm.parameters = new Asn1Null();
cms.signerInfos.elements[0].signatureAlgorithm =
new SignatureAlgorithmIdentifier(new OID(CMStools.SIGN_OID).value);
cms.signerInfos.elements[0].signatureAlgorithm.parameters = new Asn1Null();
cms.signerInfos.elements[0].signature = new SignatureValue(sign);
final Asn1BerEncodeBuffer asnBuf = new Asn1BerEncodeBuffer();
all.encode(asnBuf, true);
byte[] result = asnBuf.getMsgCopy();
Array.writeFile(FileUtils.getFile(FILE_FOR_SIGN), INPUT_DATA.getBytes(StandardCharsets.UTF_8));
Array.writeFile(FileUtils.getFile(FILE_SIGNATURE_P7S), result);
}
|
|
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 06.12.2008(UTC) Сообщений: 4,064  Откуда: Крипто-Про Сказал(а) «Спасибо»: 21 раз Поблагодарили: 740 раз в 698 постах
|
0x80090008: Указан неправильный алгоритм. Проверьте константы, которые участвуют в создании сообщения: DIGEST_OID, SIGN_OID. Это OID'ы для ГОСТ 2001, а надо, видимо, для ГОСТ 2012 (256): DIGEST_OID_2012_256, SIGN_OID_2012_256. |
|
 1 пользователь поблагодарил Евгений Афанасьев за этот пост.
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 24.10.2025(UTC) Сообщений: 3  Сказал(а) «Спасибо»: 2 раз
|
Да, Вы снова правы. Получилось, большое спасибо Вам!
|
|
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close