Atom Лента - Форум КриптоПро - Тема:Шифрование отчета Форма 4 для отправки в ФСС - 10Форум КриптоПро - Atom Лентаurn:https:--www-cryptopro-ru:AtomLenta:ForumKriptoPro:Tema:ShifrovanieotchetaForma4dljaotpravkivFSS-10:1Copyright 2024 Форум КриптоПро2024-03-29T14:49:03Zhttps://www.cryptopro.ru/forum2/Images/YAFLogo.pngForum Adminhttps://www.cryptopro.ruforum@cryptopro.ruTerroNethttps://www.cryptopro.ru/forum2/default.aspx?g=profile&u=55859&name=TerroNetTerroNethttps://www.cryptopro.ru/forum2/default.aspx?g=profile&u=55859&name=TerroNetTerroNethttps://www.cryptopro.ru/forum2/default.aspx?g=profile&u=55859&name=TerroNettwo_oceanshttps://www.cryptopro.ru/forum2/default.aspx?g=profile&u=36490&name=two_oceansTerroNethttps://www.cryptopro.ru/forum2/default.aspx?g=profile&u=55859&name=TerroNetTerroNethttps://www.cryptopro.ru/forum2/default.aspx?g=profile&u=55859&name=TerroNettwo_oceanshttps://www.cryptopro.ru/forum2/default.aspx?g=profile&u=36490&name=two_oceansTerroNethttps://www.cryptopro.ru/forum2/default.aspx?g=profile&u=55859&name=TerroNetYetAnotherForum.NETurn:https:--www-cryptopro-ru:ftPosts:st1:meid113887:1Шифрование отчета Форма 4 для отправки в ФСС<table class="content postContainer_Alt" width="100%"><tr><td>Несоответствие в параметрах 35.х и 36.х было из-за того, что мой сертификат был только для подписи. <br />И ошибка в KeyAgreement вылетала тоже поэтому.<br />Сгенерировал новый на <a rel="nofollow" href="https://www.cryptopro.ru/certsrv/" title="https://www.cryptopro.ru/certsrv/">https://www.cryptopro.ru/certsrv/</a> с параметрами "Ключ обмена и подписи", теперь файлы по ГОСТам идентичны:<br />[attach]8502[/attach]<br />Но ФСС отвечает ошибкой "-19. Файл не зашифрован или не подписан.". И зашифрованный файл по размеру меньше.<br />В чем может быть причина?</td></tr></table>2020-03-27T11:30:23+03:002020-03-27T11:30:23+03:00TerroNet<table class="content postContainer_Alt" width="100%"><tr><td>Несоответствие в параметрах 35.х и 36.х было из-за того, что мой сертификат был только для подписи. <br />И ошибка в KeyAgreement вылетала тоже поэтому.<br />Сгенерировал новый на <a rel="nofollow" href="https://www.cryptopro.ru/certsrv/" title="https://www.cryptopro.ru/certsrv/">https://www.cryptopro.ru/certsrv/</a> с параметрами "Ключ обмена и подписи", теперь файлы по ГОСТам идентичны:<br />[attach]8502[/attach]<br />Но ФСС отвечает ошибкой "-19. Файл не зашифрован или не подписан.". И зашифрованный файл по размеру меньше.<br />В чем может быть причина?</td></tr></table>urn:https:--www-cryptopro-ru:ftPosts:st1:meid113885:1Шифрование отчета Форма 4 для отправки в ФСС<table class="content postContainer" width="100%"><tr><td>Я хочу, чтобы на выходе из JCP зашифрованный файл имел такой же вид, как зашифрованный с помощью программы ФСС. Потому что последний ФСС может расшифровать и доходит до проверки ЭЦП. А сейчас останавливается уже на расшифровании.<br />Поэтому мне надо привести файл на скрине справа к такому же виду, как слева.<br />Это да, чистый формат CMS. То есть я беру отчет в xml, подписываю его ЭЦП, потом шифрую сам файл. SOAP формируется в классах, сгенерированных из wsdl описания.<br />Я поправил параметры при шифровании:<br /><div class="code"><strong>Код:</strong><div class="innercode"><pre class="line-numbers"><code class="language-java">public static byte[] encryptPKCS7(X509Certificate recipientCert, byte[] pkcs7) throws Exception {
final PublicKey recipientPublic = recipientCert.getPublicKey();
// Генерирование симметричного ключа с параметрами
// шифрования из контрольной панели.
final KeyGenerator kg = KeyGenerator.getInstance(CMStools.SEC_KEY_ALG_NAME, CRYPT_PROVIDER_NAME);
kg.init(CryptParamsSpec.getInstance(CryptParamsSpec.Rosstandart_TC26_Z));
final SecretKey simm = kg.generateKey();
// Зашифрование текста на симметричном ключе.
Cipher cipher = Cipher.getInstance(CIPHER_MODE, CRYPT_PROVIDER_NAME);
cipher.init(Cipher.ENCRYPT_MODE, simm, (SecureRandom) null);
final byte[] iv = cipher.getIV();
final byte[] text = cipher.doFinal(pkcs7, 0, pkcs7.length);
// Зашифрование симметричного ключа.
final byte[] keyTransport = wrap(simm, recipientPublic);
// Формирование CMS-сообщения.
final ContentInfo all = new ContentInfo();
all.contentType = new Asn1ObjectIdentifier(new OID(CMStools.STR_CMS_OID_ENVELOPED).value);
final EnvelopedData cms = new EnvelopedData();
all.content = cms;
cms.version = new CMSVersion(0);
cms.recipientInfos = new RecipientInfos(1);
cms.recipientInfos.elements = new RecipientInfo[1];
cms.recipientInfos.elements[0] = new RecipientInfo();
final KeyTransRecipientInfo keytrans = new KeyTransRecipientInfo();
keytrans.version = new CMSVersion(0);
final Asn1BerEncodeBuffer ebuf = new Asn1BerEncodeBuffer();
final AlgIdInterface algid = new AlgIdSpec(JCP.GOST_PARAMS_SIG_2012_256_KEY_OID);
final AlgorithmIdentifier id = (AlgorithmIdentifier) algid.getDecoded();
id.encode(ebuf);
Asn1BerDecodeBuffer dbuf = new Asn1BerDecodeBuffer(ebuf.getMsgCopy());
keytrans.keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier();
keytrans.keyEncryptionAlgorithm.decode(dbuf);
ebuf.reset();
dbuf.reset();
keytrans.rid = new RecipientIdentifier();
final IssuerAndSerialNumber issuer = new IssuerAndSerialNumber();
final X500Principal issuerName = recipientCert.getIssuerX500Principal();
dbuf = new Asn1BerDecodeBuffer(issuerName.getEncoded());
issuer.issuer = new Name();
final RDNSequence rnd = new RDNSequence();
rnd.decode(dbuf);
issuer.issuer.set_rdnSequence(rnd);
issuer.serialNumber = new CertificateSerialNumber(recipientCert.getSerialNumber());
keytrans.rid.set_issuerAndSerialNumber(issuer);
dbuf.reset();
keytrans.encryptedKey = new EncryptedKey(keyTransport);
ebuf.reset();
cms.recipientInfos.elements[0].set_ktri(keytrans);
cms.encryptedContentInfo = new EncryptedContentInfo();
final OID contentType = new OID(CMStools.STR_CMS_OID_DATA);
cms.encryptedContentInfo.contentType = new ContentType(contentType.value);
final Gost28147_89_Parameters params = new Gost28147_89_Parameters();
params.iv = new Gost28147_89_IV(iv);
params.encryptionParamSet = new Gost28147_89_ParamSet(CryptParamsSpec.getInstance(CryptParamsSpec.VERBAO).getOID().value);
cms.encryptedContentInfo.contentEncryptionAlgorithm = new ContentEncryptionAlgorithmIdentifier(
_Gost28147_89_EncryptionSyntaxValues.id_Gost28147_89, params);
cms.encryptedContentInfo.encryptedContent = new EncryptedContent(text);
all.encode(ebuf);
return ebuf.getMsgCopy();
}
private static byte[] wrap(SecretKey secretKey, Key recipientKey) throws Exception {
// Генерация эфемерной пары.
KeyPairGenerator kgp = KeyPairGenerator.getInstance(
JCP.GOST_DH_2012_256_NAME,
CRYPT_PROVIDER_NAME
);
// Устанавливаем нужные параметры, как у получателя.
kgp.initialize(new X509PublicKeySpec(recipientKey.getEncoded()));
// Генерируем эфемерную пару.
KeyPair ephPair = kgp.generateKeyPair();
PrivateKey privateKey = ephPair.getPrivate();
PublicKey publicKey = ephPair.getPublic();
byte[] syncro = new byte[8];
SecureRandom random = SecureRandom.getInstance(JCP.CP_RANDOM, PROVIDER_NAME);
random.nextBytes(syncro);
IvParameterSpec iv = new IvParameterSpec(syncro);
OID oid = CryptParamsSpec.OID_Gost28147_89_Rosstandart_TC26_Z_ParamSet;
// Выработка ключа согласования.
KeyAgreement ka = KeyAgreement.getInstance(privateKey.getAlgorithm(), CRYPT_PROVIDER_NAME);
ka.init(privateKey, iv);
ka.doPhase(recipientKey, true);
Key dh = ka.generateSecret(CIPHER);
//Зашифрование симметричного ключа на ключе согласования
// отправителя.
final Cipher cipher = Cipher.getInstance(CIPHER, CRYPT_PROVIDER_NAME);
cipher.init(Cipher.WRAP_MODE, dh, (SecureRandom) null);
final byte[] wrappedKey = cipher.wrap(secretKey);
// Упаковка параметров и ключа.
Gost28147_89_EncryptedKey encryptedKey = new Gost28147_89_EncryptedKey();
Asn1BerDecodeBuffer decoder = new Asn1BerDecodeBuffer(wrappedKey);
encryptedKey.decode(decoder);
byte[] imita = encryptedKey.macKey.value;
byte[] wrapperKeyBytes = encryptedKey.encryptedKey.value;
// Кодирование открытого ключа в SubjectPublicKeyInfo.
byte[] publicKeyBytes = publicKey.getEncoded();
SubjectPublicKeyInfo publicKeyInfo = new SubjectPublicKeyInfo();
decoder = new Asn1BerDecodeBuffer(publicKeyBytes);
publicKeyInfo.decode(decoder);
// Кодирование GostR3410_KeyTransport.
GostR3410_KeyTransport keyTransport = new GostR3410_KeyTransport();
Asn1BerEncodeBuffer encoder = new Asn1BerEncodeBuffer();
keyTransport.sessionEncryptedKey = new Gost28147_89_EncryptedKey(wrapperKeyBytes, imita);
keyTransport.transportParameters = new GostR3410_TransportParameters(
new Gost28147_89_ParamSet(oid.value),
publicKeyInfo,
new Asn1OctetString(iv.getIV()));
keyTransport.encode(encoder);
return encoder.getMsgCopy();
}</code></pre>
</div></div><br />Сервис ФСС на это отвечает ошибкой "-19. Файл не зашифрован или не подписан".<br />В файлах осталось одно отличие:<br />[attach]8500[/attach]<br />Я правильно понимаю, что этот параметр выставляется автоматически вот здесь:<br /><div class="code"><strong>Код:</strong><div class="innercode"><pre class="line-numbers"><code class="language-java">
final AlgIdInterface algid = new AlgIdSpec(JCP.GOST_PARAMS_SIG_2012_256_KEY_OID);
final AlgorithmIdentifier id = (AlgorithmIdentifier) algid.getDecoded();
id.encode(ebuf);
Asn1BerDecodeBuffer dbuf = new Asn1BerDecodeBuffer(ebuf.getMsgCopy());
keytrans.keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier();
keytrans.keyEncryptionAlgorithm.decode(dbuf);</code></pre>
</div></div><br />?<br />По поводу того, что согласования не было - вы имеете ввиду следующий пример из CMS_samples\CMSSignAndEncrypt.java?<br /><div class="code"><strong>Код:</strong><div class="innercode"><pre class="line-numbers"><code class="language-java">// выработка ключа согласования отправителем
final KeyAgreement senderKeyAgree =
KeyAgreement.getInstance(agreeAlgorithm);
senderKeyAgree.init(senderKey, new IvParameterSpec(sv), null);
senderKeyAgree.doPhase(responderPublic, true);
final SecretKey alisaSecret =
senderKeyAgree.generateSecret(CMStools.SEC_KEY_ALG_NAME);</code></pre>
</div></div><br />Если туда передать мой закрытый ключ из ЭЦП и открытый ключ сертификата ФСС, то выходит ошибка "Несоответствие параметров ключа".</td></tr></table>2020-03-27T08:54:10+03:002020-03-27T08:54:10+03:00TerroNet<table class="content postContainer" width="100%"><tr><td>Я хочу, чтобы на выходе из JCP зашифрованный файл имел такой же вид, как зашифрованный с помощью программы ФСС. Потому что последний ФСС может расшифровать и доходит до проверки ЭЦП. А сейчас останавливается уже на расшифровании.<br />Поэтому мне надо привести файл на скрине справа к такому же виду, как слева.<br />Это да, чистый формат CMS. То есть я беру отчет в xml, подписываю его ЭЦП, потом шифрую сам файл. SOAP формируется в классах, сгенерированных из wsdl описания.<br />Я поправил параметры при шифровании:<br /><div class="code"><strong>Код:</strong><div class="innercode"><pre class="line-numbers"><code class="language-java">public static byte[] encryptPKCS7(X509Certificate recipientCert, byte[] pkcs7) throws Exception {
final PublicKey recipientPublic = recipientCert.getPublicKey();
// Генерирование симметричного ключа с параметрами
// шифрования из контрольной панели.
final KeyGenerator kg = KeyGenerator.getInstance(CMStools.SEC_KEY_ALG_NAME, CRYPT_PROVIDER_NAME);
kg.init(CryptParamsSpec.getInstance(CryptParamsSpec.Rosstandart_TC26_Z));
final SecretKey simm = kg.generateKey();
// Зашифрование текста на симметричном ключе.
Cipher cipher = Cipher.getInstance(CIPHER_MODE, CRYPT_PROVIDER_NAME);
cipher.init(Cipher.ENCRYPT_MODE, simm, (SecureRandom) null);
final byte[] iv = cipher.getIV();
final byte[] text = cipher.doFinal(pkcs7, 0, pkcs7.length);
// Зашифрование симметричного ключа.
final byte[] keyTransport = wrap(simm, recipientPublic);
// Формирование CMS-сообщения.
final ContentInfo all = new ContentInfo();
all.contentType = new Asn1ObjectIdentifier(new OID(CMStools.STR_CMS_OID_ENVELOPED).value);
final EnvelopedData cms = new EnvelopedData();
all.content = cms;
cms.version = new CMSVersion(0);
cms.recipientInfos = new RecipientInfos(1);
cms.recipientInfos.elements = new RecipientInfo[1];
cms.recipientInfos.elements[0] = new RecipientInfo();
final KeyTransRecipientInfo keytrans = new KeyTransRecipientInfo();
keytrans.version = new CMSVersion(0);
final Asn1BerEncodeBuffer ebuf = new Asn1BerEncodeBuffer();
final AlgIdInterface algid = new AlgIdSpec(JCP.GOST_PARAMS_SIG_2012_256_KEY_OID);
final AlgorithmIdentifier id = (AlgorithmIdentifier) algid.getDecoded();
id.encode(ebuf);
Asn1BerDecodeBuffer dbuf = new Asn1BerDecodeBuffer(ebuf.getMsgCopy());
keytrans.keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier();
keytrans.keyEncryptionAlgorithm.decode(dbuf);
ebuf.reset();
dbuf.reset();
keytrans.rid = new RecipientIdentifier();
final IssuerAndSerialNumber issuer = new IssuerAndSerialNumber();
final X500Principal issuerName = recipientCert.getIssuerX500Principal();
dbuf = new Asn1BerDecodeBuffer(issuerName.getEncoded());
issuer.issuer = new Name();
final RDNSequence rnd = new RDNSequence();
rnd.decode(dbuf);
issuer.issuer.set_rdnSequence(rnd);
issuer.serialNumber = new CertificateSerialNumber(recipientCert.getSerialNumber());
keytrans.rid.set_issuerAndSerialNumber(issuer);
dbuf.reset();
keytrans.encryptedKey = new EncryptedKey(keyTransport);
ebuf.reset();
cms.recipientInfos.elements[0].set_ktri(keytrans);
cms.encryptedContentInfo = new EncryptedContentInfo();
final OID contentType = new OID(CMStools.STR_CMS_OID_DATA);
cms.encryptedContentInfo.contentType = new ContentType(contentType.value);
final Gost28147_89_Parameters params = new Gost28147_89_Parameters();
params.iv = new Gost28147_89_IV(iv);
params.encryptionParamSet = new Gost28147_89_ParamSet(CryptParamsSpec.getInstance(CryptParamsSpec.VERBAO).getOID().value);
cms.encryptedContentInfo.contentEncryptionAlgorithm = new ContentEncryptionAlgorithmIdentifier(
_Gost28147_89_EncryptionSyntaxValues.id_Gost28147_89, params);
cms.encryptedContentInfo.encryptedContent = new EncryptedContent(text);
all.encode(ebuf);
return ebuf.getMsgCopy();
}
private static byte[] wrap(SecretKey secretKey, Key recipientKey) throws Exception {
// Генерация эфемерной пары.
KeyPairGenerator kgp = KeyPairGenerator.getInstance(
JCP.GOST_DH_2012_256_NAME,
CRYPT_PROVIDER_NAME
);
// Устанавливаем нужные параметры, как у получателя.
kgp.initialize(new X509PublicKeySpec(recipientKey.getEncoded()));
// Генерируем эфемерную пару.
KeyPair ephPair = kgp.generateKeyPair();
PrivateKey privateKey = ephPair.getPrivate();
PublicKey publicKey = ephPair.getPublic();
byte[] syncro = new byte[8];
SecureRandom random = SecureRandom.getInstance(JCP.CP_RANDOM, PROVIDER_NAME);
random.nextBytes(syncro);
IvParameterSpec iv = new IvParameterSpec(syncro);
OID oid = CryptParamsSpec.OID_Gost28147_89_Rosstandart_TC26_Z_ParamSet;
// Выработка ключа согласования.
KeyAgreement ka = KeyAgreement.getInstance(privateKey.getAlgorithm(), CRYPT_PROVIDER_NAME);
ka.init(privateKey, iv);
ka.doPhase(recipientKey, true);
Key dh = ka.generateSecret(CIPHER);
//Зашифрование симметричного ключа на ключе согласования
// отправителя.
final Cipher cipher = Cipher.getInstance(CIPHER, CRYPT_PROVIDER_NAME);
cipher.init(Cipher.WRAP_MODE, dh, (SecureRandom) null);
final byte[] wrappedKey = cipher.wrap(secretKey);
// Упаковка параметров и ключа.
Gost28147_89_EncryptedKey encryptedKey = new Gost28147_89_EncryptedKey();
Asn1BerDecodeBuffer decoder = new Asn1BerDecodeBuffer(wrappedKey);
encryptedKey.decode(decoder);
byte[] imita = encryptedKey.macKey.value;
byte[] wrapperKeyBytes = encryptedKey.encryptedKey.value;
// Кодирование открытого ключа в SubjectPublicKeyInfo.
byte[] publicKeyBytes = publicKey.getEncoded();
SubjectPublicKeyInfo publicKeyInfo = new SubjectPublicKeyInfo();
decoder = new Asn1BerDecodeBuffer(publicKeyBytes);
publicKeyInfo.decode(decoder);
// Кодирование GostR3410_KeyTransport.
GostR3410_KeyTransport keyTransport = new GostR3410_KeyTransport();
Asn1BerEncodeBuffer encoder = new Asn1BerEncodeBuffer();
keyTransport.sessionEncryptedKey = new Gost28147_89_EncryptedKey(wrapperKeyBytes, imita);
keyTransport.transportParameters = new GostR3410_TransportParameters(
new Gost28147_89_ParamSet(oid.value),
publicKeyInfo,
new Asn1OctetString(iv.getIV()));
keyTransport.encode(encoder);
return encoder.getMsgCopy();
}</code></pre>
</div></div><br />Сервис ФСС на это отвечает ошибкой "-19. Файл не зашифрован или не подписан".<br />В файлах осталось одно отличие:<br />[attach]8500[/attach]<br />Я правильно понимаю, что этот параметр выставляется автоматически вот здесь:<br /><div class="code"><strong>Код:</strong><div class="innercode"><pre class="line-numbers"><code class="language-java">
final AlgIdInterface algid = new AlgIdSpec(JCP.GOST_PARAMS_SIG_2012_256_KEY_OID);
final AlgorithmIdentifier id = (AlgorithmIdentifier) algid.getDecoded();
id.encode(ebuf);
Asn1BerDecodeBuffer dbuf = new Asn1BerDecodeBuffer(ebuf.getMsgCopy());
keytrans.keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier();
keytrans.keyEncryptionAlgorithm.decode(dbuf);</code></pre>
</div></div><br />?<br />По поводу того, что согласования не было - вы имеете ввиду следующий пример из CMS_samples\CMSSignAndEncrypt.java?<br /><div class="code"><strong>Код:</strong><div class="innercode"><pre class="line-numbers"><code class="language-java">// выработка ключа согласования отправителем
final KeyAgreement senderKeyAgree =
KeyAgreement.getInstance(agreeAlgorithm);
senderKeyAgree.init(senderKey, new IvParameterSpec(sv), null);
senderKeyAgree.doPhase(responderPublic, true);
final SecretKey alisaSecret =
senderKeyAgree.generateSecret(CMStools.SEC_KEY_ALG_NAME);</code></pre>
</div></div><br />Если туда передать мой закрытый ключ из ЭЦП и открытый ключ сертификата ФСС, то выходит ошибка "Несоответствие параметров ключа".</td></tr></table>urn:https:--www-cryptopro-ru:ftPosts:st1:meid113882:1Шифрование отчета Форма 4 для отправки в ФССБолее удивительно, что (где выделено красным) с одной стороны <strong>35</strong>.х, а с другой <strong>36</strong>.х - в соседней теме было о том что легко ошибиться когда разные параметры при выработке ключа согласования - автоматика выставляет по одному из сертификатов и не всегда верно. То есть или исправили корректно или на самом деле разные сертификаты с разными параметрами или справа все же непонятный подформат (в этом случае вероятно что согласования не было).2020-03-27T05:43:16+03:002020-03-27T05:43:16+03:00two_oceansБолее удивительно, что (где выделено красным) с одной стороны <strong>35</strong>.х, а с другой <strong>36</strong>.х - в соседней теме было о том что легко ошибиться когда разные параметры при выработке ключа согласования - автоматика выставляет по одному из сертификатов и не всегда верно. То есть или исправили корректно или на самом деле разные сертификаты с разными параметрами или справа все же непонятный подформат (в этом случае вероятно что согласования не было).urn:https:--www-cryptopro-ru:ftPosts:st1:meid113870:1Шифрование отчета Форма 4 для отправки в ФСС<table class="content postContainer" width="100%"><tr><td>Вот еще в чем нашел различия:<br />слева - зашифровано через программу ФСС, справа - через JCP<br />[attach]8498[/attach]<br />[attach]8499[/attach]<br />Сертификат ФСС по ГОСТ 2012.<br />Я не совсем понимаю, получается, JCP шифрует по ГОСТ2001 сертификатом 2012? Или это симметричный ключ генерируется по ГОСТ2001?</td></tr></table>2020-03-26T17:12:24+03:002020-03-26T17:12:24+03:00TerroNet<table class="content postContainer" width="100%"><tr><td>Вот еще в чем нашел различия:<br />слева - зашифровано через программу ФСС, справа - через JCP<br />[attach]8498[/attach]<br />[attach]8499[/attach]<br />Сертификат ФСС по ГОСТ 2012.<br />Я не совсем понимаю, получается, JCP шифрует по ГОСТ2001 сертификатом 2012? Или это симметричный ключ генерируется по ГОСТ2001?</td></tr></table>urn:https:--www-cryptopro-ru:ftPosts:st1:meid113856:1Шифрование отчета Форма 4 для отправки в ФСС<table class="content postContainer_Alt" width="100%"><tr><td><div class="quote"><span class="quotetitle">Автор: two_oceans <a href="/forum2/default.aspx?g=posts&m=113855#post113855"><img src="/forum2/Themes/soclean/icon_latest_reply.gif" title="Перейти к цитате" alt="Перейти к цитате" /></a></span><blockquote>Похоже на примерно верное до комментария о формировании cms. SOAP конечно не сами формируете, но на мой взгляд слишком много свойств устанавливаете для cms, так что это почти неотличимо от самостоятельного формирования.</div></div><br /><br />Код шифрования взят из примера CMS_samples/PKCS7EnvEphTransport.java.<br />Если сравнить файлы после шифрования программой ФСС и через JCP, то в том, который сформирован через JCP, данных больше.<br />Попробовал убрать поочередно свойства для cms - всегда выходит NullPointerException. Они все обязательные.</td></tr></table>2020-03-26T16:12:01+03:002020-03-26T16:12:01+03:00TerroNet<table class="content postContainer_Alt" width="100%"><tr><td><div class="quote"><span class="quotetitle">Автор: two_oceans <a href="/forum2/default.aspx?g=posts&m=113855#post113855"><img src="/forum2/Themes/soclean/icon_latest_reply.gif" title="Перейти к цитате" alt="Перейти к цитате" /></a></span><blockquote>Похоже на примерно верное до комментария о формировании cms. SOAP конечно не сами формируете, но на мой взгляд слишком много свойств устанавливаете для cms, так что это почти неотличимо от самостоятельного формирования.</div></div><br /><br />Код шифрования взят из примера CMS_samples/PKCS7EnvEphTransport.java.<br />Если сравнить файлы после шифрования программой ФСС и через JCP, то в том, который сформирован через JCP, данных больше.<br />Попробовал убрать поочередно свойства для cms - всегда выходит NullPointerException. Они все обязательные.</td></tr></table>urn:https:--www-cryptopro-ru:ftPosts:st1:meid113855:1Шифрование отчета Форма 4 для отправки в ФСС<table class="content postContainer" width="100%"><tr><td>Похоже на примерно верное до комментария о формировании cms. SOAP конечно не сами формируете, но на мой взгляд слишком много свойств устанавливаете для cms, так что это почти неотличимо от самостоятельного формирования.</td></tr></table>2020-03-26T13:22:10+03:002020-03-26T13:22:10+03:00two_oceans<table class="content postContainer" width="100%"><tr><td>Похоже на примерно верное до комментария о формировании cms. SOAP конечно не сами формируете, но на мой взгляд слишком много свойств устанавливаете для cms, так что это почти неотличимо от самостоятельного формирования.</td></tr></table>urn:https:--www-cryptopro-ru:ftPosts:st1:meid113844:1Шифрование отчета Форма 4 для отправки в ФСС<table class="content postContainer_Alt" width="100%"><tr><td>Здравствуйте!<br />Пытаюсь подписать, зашифровать отчет по Форме 4 через CryptoPro JCP и отправить в ФСС через их веб-сервис.<br />Тестовый шлюз ФСС - <a rel="nofollow" href="http://docs-test.fss.ru/" title="http://docs-test.fss.ru/">http://docs-test.fss.ru/</a><br />Тестовую ЭЦП получил здесь <a rel="nofollow" href="https://www.cryptopro.ru/certsrv/" title="https://www.cryptopro.ru/certsrv/">https://www.cryptopro.ru/certsrv/</a><br />Сертификат ФСС, которым шифрую подписанный отчет: [attach]8494[/attach]<br />Когда подписываю и шифрую через их программу <a rel="nofollow" href="https://fss.ru/ru/fund/download/55833/index.shtml," title="https://fss.ru/ru/fund/download/55833/index.shtml,">https://fss.ru/ru/fund/download/55833/index.shtml,</a> потом полученный файл [attach]8495[/attach] загружаю вручную через <a rel="nofollow" href="http://docs-test.fss.ru/home/upload," title="http://docs-test.fss.ru/home/upload,">http://docs-test.fss.ru/home/upload,</a> то выдает ошибку "-41. Нет доверия к издателю сертификата". То есть файл расшифровывается, а ЭЦП проверку не проходит. Вроде логично.<br />Теперь пытаюсь подписать и зашифровать файл через JCP следующим образом:<br />подпись файла тестовой ЭЦП<br /><div class="code"><strong>Код:</strong><div class="innercode"><pre class="line-numbers"><code class="language-java">private byte[] signDoc(String keyPairAlgorithm, String keyProvider,
String signAlgorithm, String signProvider, String certName,
String signMethod, String digestMethod, File testDoc, String signDoc)
throws Exception {
// инициализация объекта чтения XML-документа
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// установка флага, определяющего игнорирование пробелов в содержимом элементов при обработке XML-документа
dbf.setIgnoringElementContentWhitespace(true);
// установка флага, определяющего преобразование узлов CDATA в текстовые узлы при обработке XML-документа
dbf.setCoalescing(true);
// установка флага, определяющего поддержку пространств имен при обработке XML-документа
dbf.setNamespaceAware(true);
// загрузка содержимого подписываемого документа на основе установленных флагами правил
final DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
final Document doc;
doc = documentBuilder.parse(getClass()
.getResourceAsStream("/5205022875_2019_12.xml"));
/* Добавление узла подписи <ds:Signature> в загруженный XML-документ */
// инициализация объекта формирования ЭЦП в соответствии с алгоритмом ГОСТ Р 34.10-2001
final XMLSignature sig = new XMLSignature(doc, "", signMethod);
// получение корневого узла XML-документа
final Element anElement = doc.getDocumentElement();
// добавление в корневой узел XML-документа узла подписи
anElement.appendChild(sig.getElement());
/* Определение правил работы с XML-документом и добавление в узел подписи этих правил */
// создание узла преобразований <ds:Transforms> обрабатываемого XML-документа
final Transforms transforms = new Transforms(doc);
// добавление в узел преобразований правил работы с документом
transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
transforms.addTransform(Transforms.TRANSFORM_C14N_WITH_COMMENTS);
// добавление в узел подписи ссылок (узла <ds:Reference>), определяющих правила работы с
// XML-документом (обрабатывается текущий документ с заданными в узле <ds:Transforms> правилами
// и заданным алгоритмом хеширования)
sig.addDocument("", transforms, digestMethod);
/* Создание подписи всего содержимого XML-документа на основе закрытого ключа, заданных правил и алгоритмов */
KeyStore keyStore = KeyStore.getInstance(JCP.HD_STORE_NAME, JCP.PROVIDER_NAME);
keyStore.load(null, null);
PrivateKey key = (PrivateKey)keyStore.getKey(containerName, containerPass == null ? null : containerPass.toCharArray());
Certificate[] chain = keyStore.getCertificateChain(containerName);
// создание внутри узла подписи узла <ds:KeyInfo> информации об открытом ключе на основе
// сертификата
sig.addKeyInfo((X509Certificate)chain[0]);
// создание подписи XML-документа
sig.sign(key);
/* Сохранение подписанного XML-документа в файл */
// определение потока, в который осуществляется запись подписанного XML-документа
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// инициализация объекта копирования содержимого XML-документа в поток
final TransformerFactory tf = TransformerFactory.newInstance();
// создание объекта копирования содержимого XML-документа в поток
final Transformer trans = tf.newTransformer();
// копирование содержимого XML-документа в поток
trans.transform(new DOMSource(doc), new StreamResult(baos));
byte[] signedBytes = baos.toByteArray();
baos.close();
// шифрование ключом ФСС
CertificateFactory cf = CertificateFactory.getInstance("X509");
Certificate cer = cf.generateCertificate(getClass()
.getResourceAsStream("/fss2012Test.cer"));
return PKCS7EnvEphTransport.encryptPKCS7((X509Certificate) cer, signedBytes);
}</code></pre>
</div></div><br /><br />шифрование подписанного файла ключом ФСС:<br /><div class="code"><strong>Код:</strong><div class="innercode"><pre class="line-numbers"><code class="language-java">public static byte[] encryptPKCS7(X509Certificate recipientCert, byte[] pkcs7) throws Exception {
final PublicKey recipientPublic = recipientCert.getPublicKey();
// Генерирование симметричного ключа с параметрами
// шифрования из контрольной панели.
final KeyGenerator kg = KeyGenerator.getInstance(CMStools.SEC_KEY_ALG_NAME, CRYPT_PROVIDER_NAME);
final ParamsInterface paramss = AlgIdSpec.getDefaultCryptParams();
kg.init(CryptParamsSpec.getInstance(CryptParamsSpec.Rosstandart_TC26_Z));
final SecretKey simm = kg.generateKey();
// Зашифрование текста на симметричном ключе.
Cipher cipher = Cipher.getInstance(CIPHER_MODE, CRYPT_PROVIDER_NAME);
cipher.init(Cipher.ENCRYPT_MODE, simm, (SecureRandom) null);
final byte[] iv = cipher.getIV();
final byte[] text = cipher.doFinal(pkcs7, 0, pkcs7.length);
// Зашифрование симметричного ключа.
final byte[] keyTransport = wrap(simm, recipientPublic);
// Формирование CMS-сообщения.
final ContentInfo all = new ContentInfo();
all.contentType = new Asn1ObjectIdentifier(new OID(CMStools.STR_CMS_OID_SIGNED).value);
final EnvelopedData cms = new EnvelopedData();
all.content = cms;
cms.version = new CMSVersion(0);
cms.recipientInfos = new RecipientInfos(1);
cms.recipientInfos.elements = new RecipientInfo[1];
cms.recipientInfos.elements[0] = new RecipientInfo();
final KeyTransRecipientInfo keytrans = new KeyTransRecipientInfo();
keytrans.version = new CMSVersion(0);
final Asn1BerEncodeBuffer ebuf = new Asn1BerEncodeBuffer();
final AlgIdInterface algid = new AlgIdSpec(JCP.GOST_EL_KEY_OID);
final AlgorithmIdentifier id = (AlgorithmIdentifier) algid.getDecoded();
id.encode(ebuf);
Asn1BerDecodeBuffer dbuf = new Asn1BerDecodeBuffer(ebuf.getMsgCopy());
keytrans.keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier();
keytrans.keyEncryptionAlgorithm.decode(dbuf);
ebuf.reset();
dbuf.reset();
keytrans.rid = new RecipientIdentifier();
final IssuerAndSerialNumber issuer = new IssuerAndSerialNumber();
final X500Principal issuerName = recipientCert.getIssuerX500Principal();
dbuf = new Asn1BerDecodeBuffer(issuerName.getEncoded());
issuer.issuer = new Name();
final RDNSequence rnd = new RDNSequence();
rnd.decode(dbuf);
issuer.issuer.set_rdnSequence(rnd);
issuer.serialNumber = new CertificateSerialNumber(recipientCert.getSerialNumber());
keytrans.rid.set_issuerAndSerialNumber(issuer);
dbuf.reset();
keytrans.encryptedKey = new EncryptedKey(keyTransport);
ebuf.reset();
cms.recipientInfos.elements[0].set_ktri(keytrans);
cms.encryptedContentInfo = new EncryptedContentInfo();
final OID contentType = new OID(CMStools.STR_CMS_OID_DATA);
cms.encryptedContentInfo.contentType = new ContentType(contentType.value);
final Gost28147_89_Parameters params = new Gost28147_89_Parameters();
params.iv = new Gost28147_89_IV(iv);
params.encryptionParamSet = new Gost28147_89_ParamSet(paramss.getOID().value);
cms.encryptedContentInfo.contentEncryptionAlgorithm = new ContentEncryptionAlgorithmIdentifier(
_Gost28147_89_EncryptionSyntaxValues.id_Gost28147_89, params);
cms.encryptedContentInfo.encryptedContent = new EncryptedContent(text);
all.encode(ebuf);
return ebuf.getMsgCopy();
}</code></pre>
</div></div><br /><br />Потом полученный массив байтов отправляю через веб-сервис в ФСС, т.е. SOAP конверт сам не формирую:<br /><div class="code"><strong>Код:</strong><div class="innercode"><pre class="line-numbers"><code class="language-java">GatewayService gatewayService = new GatewayService();
IGatewayService service = gatewayService.getBasicHttpBindingIGatewayService();
UploadResult result = service.sendFile(encryptedBytes, "E_" + fileName + ".ef4");</code></pre>
</div></div><br />В результате возвращается ошибка "-10. He удалось расшифровать".<br />Т.е. до проверки ЭЦП даже не доходит.<br />Если таким же образом отправляю файл, полученный через программу ФСС, выдает ошибку -41 также, как и через веб-интерфейс.<br />Файл, который получается после шифрования в JCP: [attach]8496[/attach]<br />Подскажите, как правильно зашифровать ключом ФСС подписанный файл?</td></tr></table>2020-03-26T10:07:54+03:002020-03-26T10:07:54+03:00TerroNet<table class="content postContainer_Alt" width="100%"><tr><td>Здравствуйте!<br />Пытаюсь подписать, зашифровать отчет по Форме 4 через CryptoPro JCP и отправить в ФСС через их веб-сервис.<br />Тестовый шлюз ФСС - <a rel="nofollow" href="http://docs-test.fss.ru/" title="http://docs-test.fss.ru/">http://docs-test.fss.ru/</a><br />Тестовую ЭЦП получил здесь <a rel="nofollow" href="https://www.cryptopro.ru/certsrv/" title="https://www.cryptopro.ru/certsrv/">https://www.cryptopro.ru/certsrv/</a><br />Сертификат ФСС, которым шифрую подписанный отчет: [attach]8494[/attach]<br />Когда подписываю и шифрую через их программу <a rel="nofollow" href="https://fss.ru/ru/fund/download/55833/index.shtml," title="https://fss.ru/ru/fund/download/55833/index.shtml,">https://fss.ru/ru/fund/download/55833/index.shtml,</a> потом полученный файл [attach]8495[/attach] загружаю вручную через <a rel="nofollow" href="http://docs-test.fss.ru/home/upload," title="http://docs-test.fss.ru/home/upload,">http://docs-test.fss.ru/home/upload,</a> то выдает ошибку "-41. Нет доверия к издателю сертификата". То есть файл расшифровывается, а ЭЦП проверку не проходит. Вроде логично.<br />Теперь пытаюсь подписать и зашифровать файл через JCP следующим образом:<br />подпись файла тестовой ЭЦП<br /><div class="code"><strong>Код:</strong><div class="innercode"><pre class="line-numbers"><code class="language-java">private byte[] signDoc(String keyPairAlgorithm, String keyProvider,
String signAlgorithm, String signProvider, String certName,
String signMethod, String digestMethod, File testDoc, String signDoc)
throws Exception {
// инициализация объекта чтения XML-документа
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// установка флага, определяющего игнорирование пробелов в содержимом элементов при обработке XML-документа
dbf.setIgnoringElementContentWhitespace(true);
// установка флага, определяющего преобразование узлов CDATA в текстовые узлы при обработке XML-документа
dbf.setCoalescing(true);
// установка флага, определяющего поддержку пространств имен при обработке XML-документа
dbf.setNamespaceAware(true);
// загрузка содержимого подписываемого документа на основе установленных флагами правил
final DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
final Document doc;
doc = documentBuilder.parse(getClass()
.getResourceAsStream("/5205022875_2019_12.xml"));
/* Добавление узла подписи <ds:Signature> в загруженный XML-документ */
// инициализация объекта формирования ЭЦП в соответствии с алгоритмом ГОСТ Р 34.10-2001
final XMLSignature sig = new XMLSignature(doc, "", signMethod);
// получение корневого узла XML-документа
final Element anElement = doc.getDocumentElement();
// добавление в корневой узел XML-документа узла подписи
anElement.appendChild(sig.getElement());
/* Определение правил работы с XML-документом и добавление в узел подписи этих правил */
// создание узла преобразований <ds:Transforms> обрабатываемого XML-документа
final Transforms transforms = new Transforms(doc);
// добавление в узел преобразований правил работы с документом
transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
transforms.addTransform(Transforms.TRANSFORM_C14N_WITH_COMMENTS);
// добавление в узел подписи ссылок (узла <ds:Reference>), определяющих правила работы с
// XML-документом (обрабатывается текущий документ с заданными в узле <ds:Transforms> правилами
// и заданным алгоритмом хеширования)
sig.addDocument("", transforms, digestMethod);
/* Создание подписи всего содержимого XML-документа на основе закрытого ключа, заданных правил и алгоритмов */
KeyStore keyStore = KeyStore.getInstance(JCP.HD_STORE_NAME, JCP.PROVIDER_NAME);
keyStore.load(null, null);
PrivateKey key = (PrivateKey)keyStore.getKey(containerName, containerPass == null ? null : containerPass.toCharArray());
Certificate[] chain = keyStore.getCertificateChain(containerName);
// создание внутри узла подписи узла <ds:KeyInfo> информации об открытом ключе на основе
// сертификата
sig.addKeyInfo((X509Certificate)chain[0]);
// создание подписи XML-документа
sig.sign(key);
/* Сохранение подписанного XML-документа в файл */
// определение потока, в который осуществляется запись подписанного XML-документа
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// инициализация объекта копирования содержимого XML-документа в поток
final TransformerFactory tf = TransformerFactory.newInstance();
// создание объекта копирования содержимого XML-документа в поток
final Transformer trans = tf.newTransformer();
// копирование содержимого XML-документа в поток
trans.transform(new DOMSource(doc), new StreamResult(baos));
byte[] signedBytes = baos.toByteArray();
baos.close();
// шифрование ключом ФСС
CertificateFactory cf = CertificateFactory.getInstance("X509");
Certificate cer = cf.generateCertificate(getClass()
.getResourceAsStream("/fss2012Test.cer"));
return PKCS7EnvEphTransport.encryptPKCS7((X509Certificate) cer, signedBytes);
}</code></pre>
</div></div><br /><br />шифрование подписанного файла ключом ФСС:<br /><div class="code"><strong>Код:</strong><div class="innercode"><pre class="line-numbers"><code class="language-java">public static byte[] encryptPKCS7(X509Certificate recipientCert, byte[] pkcs7) throws Exception {
final PublicKey recipientPublic = recipientCert.getPublicKey();
// Генерирование симметричного ключа с параметрами
// шифрования из контрольной панели.
final KeyGenerator kg = KeyGenerator.getInstance(CMStools.SEC_KEY_ALG_NAME, CRYPT_PROVIDER_NAME);
final ParamsInterface paramss = AlgIdSpec.getDefaultCryptParams();
kg.init(CryptParamsSpec.getInstance(CryptParamsSpec.Rosstandart_TC26_Z));
final SecretKey simm = kg.generateKey();
// Зашифрование текста на симметричном ключе.
Cipher cipher = Cipher.getInstance(CIPHER_MODE, CRYPT_PROVIDER_NAME);
cipher.init(Cipher.ENCRYPT_MODE, simm, (SecureRandom) null);
final byte[] iv = cipher.getIV();
final byte[] text = cipher.doFinal(pkcs7, 0, pkcs7.length);
// Зашифрование симметричного ключа.
final byte[] keyTransport = wrap(simm, recipientPublic);
// Формирование CMS-сообщения.
final ContentInfo all = new ContentInfo();
all.contentType = new Asn1ObjectIdentifier(new OID(CMStools.STR_CMS_OID_SIGNED).value);
final EnvelopedData cms = new EnvelopedData();
all.content = cms;
cms.version = new CMSVersion(0);
cms.recipientInfos = new RecipientInfos(1);
cms.recipientInfos.elements = new RecipientInfo[1];
cms.recipientInfos.elements[0] = new RecipientInfo();
final KeyTransRecipientInfo keytrans = new KeyTransRecipientInfo();
keytrans.version = new CMSVersion(0);
final Asn1BerEncodeBuffer ebuf = new Asn1BerEncodeBuffer();
final AlgIdInterface algid = new AlgIdSpec(JCP.GOST_EL_KEY_OID);
final AlgorithmIdentifier id = (AlgorithmIdentifier) algid.getDecoded();
id.encode(ebuf);
Asn1BerDecodeBuffer dbuf = new Asn1BerDecodeBuffer(ebuf.getMsgCopy());
keytrans.keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier();
keytrans.keyEncryptionAlgorithm.decode(dbuf);
ebuf.reset();
dbuf.reset();
keytrans.rid = new RecipientIdentifier();
final IssuerAndSerialNumber issuer = new IssuerAndSerialNumber();
final X500Principal issuerName = recipientCert.getIssuerX500Principal();
dbuf = new Asn1BerDecodeBuffer(issuerName.getEncoded());
issuer.issuer = new Name();
final RDNSequence rnd = new RDNSequence();
rnd.decode(dbuf);
issuer.issuer.set_rdnSequence(rnd);
issuer.serialNumber = new CertificateSerialNumber(recipientCert.getSerialNumber());
keytrans.rid.set_issuerAndSerialNumber(issuer);
dbuf.reset();
keytrans.encryptedKey = new EncryptedKey(keyTransport);
ebuf.reset();
cms.recipientInfos.elements[0].set_ktri(keytrans);
cms.encryptedContentInfo = new EncryptedContentInfo();
final OID contentType = new OID(CMStools.STR_CMS_OID_DATA);
cms.encryptedContentInfo.contentType = new ContentType(contentType.value);
final Gost28147_89_Parameters params = new Gost28147_89_Parameters();
params.iv = new Gost28147_89_IV(iv);
params.encryptionParamSet = new Gost28147_89_ParamSet(paramss.getOID().value);
cms.encryptedContentInfo.contentEncryptionAlgorithm = new ContentEncryptionAlgorithmIdentifier(
_Gost28147_89_EncryptionSyntaxValues.id_Gost28147_89, params);
cms.encryptedContentInfo.encryptedContent = new EncryptedContent(text);
all.encode(ebuf);
return ebuf.getMsgCopy();
}</code></pre>
</div></div><br /><br />Потом полученный массив байтов отправляю через веб-сервис в ФСС, т.е. SOAP конверт сам не формирую:<br /><div class="code"><strong>Код:</strong><div class="innercode"><pre class="line-numbers"><code class="language-java">GatewayService gatewayService = new GatewayService();
IGatewayService service = gatewayService.getBasicHttpBindingIGatewayService();
UploadResult result = service.sendFile(encryptedBytes, "E_" + fileName + ".ef4");</code></pre>
</div></div><br />В результате возвращается ошибка "-10. He удалось расшифровать".<br />Т.е. до проверки ЭЦП даже не доходит.<br />Если таким же образом отправляю файл, полученный через программу ФСС, выдает ошибку -41 также, как и через веб-интерфейс.<br />Файл, который получается после шифрования в JCP: [attach]8496[/attach]<br />Подскажите, как правильно зашифровать ключом ФСС подписанный файл?</td></tr></table>