Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ЭЛН 2.0 #39

Open
spiridonovav opened this issue Jan 23, 2021 · 90 comments
Open

ЭЛН 2.0 #39

spiridonovav opened this issue Jan 23, 2021 · 90 comments

Comments

@spiridonovav
Copy link

Здравствуйте, коллеги!
С 2017 года используем GostCryptography для взаимодействия с ФСС в части обмена данными ЭЛН. За библиотеку Автору отдельное спасибо. Все прекрасно работало, до появления сервиса версии 2.0.

С появлением нового сервиса, на запрос ЭЛН по № и СНИЛС (в тестовый контур https://docs-test.fss.ru/ws-insurer-crypto-v20/FileOperationsLnService), всегда возвращается ошибка: "ru.fss.integration.ws.fault.v01.InternalException: Не удалось расшифровать сообщение. Возможно сообщение зашифровано на ключе отличном от ключа уполномоченного лица ФСС. Проверьте правильность и актуальность ключа уполномоченного лица ФСС. class ru.ibs.cryptopro.jcp.eln.crypt.CryptoException".

В процессе отладки удалось выяснить, что тестовый контур ЭЛН 2.0 не принимает сертификат уполномоченного лица ФСС для тестового контура (https://cabinets-test.fss.ru/FSS_TEST_CERT_2021.cer), а только сертификат для рабочего контура (https://cabinets.fss.ru/FSS_PROD_CERT_2021.cer). Также тестовый контур 2.0 (в отличии от тестового контура 1.1) не принимает тестовые сертификаты (выданные тестовыми УЦ), а только выданные акредитованными УЦ (т.е. полноценные сертификаты).

При выполнении этих условий АРМ ФСС выполняет запрос ЭЛН по № и СНИЛС и ему сервис возвращает: "Ошибка: ORA-20001: Некорректные параметры: Рег. номер в запросе и ОГРН в сертификате ЭП. Не найден страхователь с такими параметрами, а также отсутствует уполномоченный представитель с таким сертификатом ЭП". Что, в общем корректно (если не обращать внимание, что контур тестовый), так как используется сертификат страхователя, который не участвует в обмене данными ЭЛН.

Запрос в тестовый контур ЭЛН 2.0 без шифрования данных (https://docs-test.fss.ru/ws-insurer-v20/FileOperationsLnService) выполняется и сервис возвращает: "ORA-20001: Номер 306735316028 принадлежит к ЛН на бумажном бланке". Что тоже выглядит корректно. То есть, на лицо проблема с шифрованием (или расшифровыванием на стороне ФСС) сообщения.

Код метода и текст сообщения, передаваемое сервису ФСС в следующих сообщениях.

Кто ни будь подскажите, в чем моя ошибка.

@spiridonovav
Copy link
Author

Код метода шифрования:

` var publicKeyFSS = (GostAsymmetricAlgorithm)fssCert.GetPublicKeyAlgorithm();
var element = (XmlElement)elements[0];
// Создание случайного сессионного ключа
using (var sessionKey = new Gost_28147_89_SymmetricAlgorithm())
{
// Шифрация элемента
var encryptedData = encryptedXml.EncryptData(element, sessionKey, false);

                // Шифрация сессионного ключа с использованием общего симметричного ключа
                var encryptedSessionKeyData = GostEncryptedXml.EncryptKey(sessionKey, publicKeyFSS);

                // Формирование элемента EncryptedData
                var elementEncryptedData = new EncryptedData();
                elementEncryptedData.Id = "EncryptedElement1";
                elementEncryptedData.Type = EncryptedXml.XmlEncElementContentUrl;
                elementEncryptedData.EncryptionMethod = new EncryptionMethod(sessionKey.AlgorithmName);
                elementEncryptedData.CipherData.CipherValue = encryptedData;
                elementEncryptedData.KeyInfo = new KeyInfo();

                // Формирование информации о зашифрованном сессионном ключе
                var encryptedSessionKey = new EncryptedKey();
                encryptedSessionKey.CipherData = new CipherData(encryptedSessionKeyData);
                //ФСС использует устаревший идентификатор
                //encryptedSessionKey.EncryptionMethod = new EncryptionMethod(publicKey.KeyExchangeAlgorithm);
                encryptedSessionKey.EncryptionMethod = new EncryptionMethod(GostCryptography.Gost_R3410.Gost_R3410_2001_AsymmetricAlgorithm.KeyExchangeAlgorithmValue);
                encryptedSessionKey.AddReference(new DataReference { Uri = "#" + elementEncryptedData.Id });
                //encryptedSessionKey.KeyInfo.AddClause(new KeyInfoName { Value = "SharedKey1" });
                encryptedSessionKey.KeyInfo.AddClause(new KeyInfoX509Data(insCert));

                // Добавление ссылки на зашифрованный ключ, используемый при шифровании данных
                elementEncryptedData.KeyInfo.AddClause(new KeyInfoEncryptedKey(encryptedSessionKey));

                var newDoc = new XmlDocument() { PreserveWhitespace = true };
                newDoc.LoadXml(SOAPMessageStr);

                // Замена элемента его зашифрованным представлением
                GostEncryptedXml.ReplaceElement((XmlElement)newDoc.GetElementsByTagName("Body", xmlsoapNamespace)[0], elementEncryptedData, true);

                return newDoc;
            }`

@spiridonovav
Copy link
Author

spiridonovav commented Jan 23, 2021

Текст зашифрованного сообщения:
<?xml version="1.0" encoding="UTF-8"?> <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Header /> <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><EncryptedData Id="EncryptedElement1" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns="http://www.w3.org/2001/04/xmlenc#"><EncryptionMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gost28147" /><KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"><EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#"><EncryptionMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:transport-gost2001" /><KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"><X509Data><X509Certificate>...</X509Certificate></X509Data></KeyInfo><CipherData><CipherValue>...</CipherValue></CipherData><ReferenceList><DataReference URI="#EncryptedElement1" /></ReferenceList></EncryptedKey></KeyInfo><CipherData><CipherValue>...</CipherValue></CipherData></EncryptedData></s:Body> </s:Envelope>

@AlexMAS
Copy link
Owner

AlexMAS commented Jan 24, 2021

Здравствуйте. Насколько я помню, ранее была проблема с использованием устаревшего ID. Возможно они изменили что-то в этой части.

//ФСС использует устаревший идентификатор
//encryptedSessionKey.EncryptionMethod = new EncryptionMethod(publicKey.KeyExchangeAlgorithm);

encryptedSessionKey.EncryptionMethod = new EncryptionMethod(GostCryptography.Gost_R3410.Gost_R3410_2001_AsymmetricAlgorithm.KeyExchangeAlgorithmValue);

@DPonomarchuk
Copy link

Я занимался сервисом МО, а не страхователя, но для меня это работает так:

  1. При отправке запроса с шифрованием проверьте что в <Header></Header> исходного сообщения (еще до шифрования) добавлен тег <X509Certificate xmlns="http://www.w3.org/2000/09/xmldsig#"></X509Certificate> содержащий ваш тестовый сертификат
  2. Взаимодействие с сервисом с шифрованием https://docs-test.fss.ru/WSLnCryptoV20/FileOperationsLnService?WSDL работает именно с сертификатом https://docs-test.fss.ru/FSS_TEST_CERT_2021.cer
  3. Тестовый контур принимает тестовые сертификаты Vipnet http://testcert.infotecs.ru/ . Был какой-то период, что они удалили на тестовом контуре сертификат УЦ из доверенных и отбраковывали тестовые сертификаты по "ошибка построения цепочки...".

Я считаю что если шифрование работало в версии 1.1, то вам нужно написать в чат разработчиков ФСС в телеграмм (возможно там кто-то сталкивался с таким) и ваша проблема не имеет отношения к библиотеке GostCryptography

Моё зашифрованное сообщение выглядит так:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header/> <SOAP-ENV:Body> <EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns="http://www.w3.org/2001/04/xmlenc#"> <EncryptionMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gost28147"/> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#"> <EncryptionMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:transport-gost2001"/> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <X509Data> <X509Certificate></X509Certificate> </X509Data> </KeyInfo> <CipherData> <CipherValue></CipherValue> </CipherData> </EncryptedKey> </KeyInfo> <CipherData> <CipherValue></CipherValue> </CipherData> </EncryptedData> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

@spiridonovav
Copy link
Author

Большое спасибо за ответ.

Я занимался сервисом МО, а не страхователя, но для меня это работает так:

  1. При отправке запроса с шифрованием проверьте что в <Header></Header> исходного сообщения (еще до шифрования) добавлен тег <X509Certificate xmlns="http://www.w3.org/2000/09/xmldsig#"></X509Certificate> содержащий ваш тестовый сертификат

Я не внимательно прочитал спецификацию 2.0. После сравнения текстов 1.1 с 2.0 я увидел, что они перенесли сертификат отправителя (страхователя) в тело шифруемого сообщения, а в KeyInfo нужно класть сертификат уполномоченного лица ФСС.
Это я исправил, сервис стал выдавать такую ошибку: "ru.fss.integration.ws.fault.v01.InternalException: Error in execution of data encrypting/decrypting operation. class org.apache.xml.security.encryption.XMLEncryptionException."

Возможно я неправильно помещаю свой сертификат в Header?
В спецификации об этом написано (в двух местах) так:

  1. "В блоке soapenv:Header в подписанном запросе добавляется блок , который содержит публичный сертификат пользователя в формате x509v3 (кодировке base64)."
  2. "В блоке soapenv:Header исходного шифруемого сообщения необходимо добавить блок , содержащий публичный ключ сертификата отправителя. Структура сообщения для шифрования после этого будет выглядеть следующим образом:"

Я это делал двумя способами:
var bsToken = request.CreateElement("", "X509Certificate", "http://www.w3.org/2000/09/xmldsig#"); bsToken.InnerText = Convert.ToBase64String(insCert.GetPublicKey()); //bsToken.InnerText = Convert.ToBase64String(insCert.RawData); header[0].AppendChild(bsToken);

  1. Взаимодействие с сервисом с шифрованием https://docs-test.fss.ru/WSLnCryptoV20/FileOperationsLnService?WSDL работает именно с сертификатом https://docs-test.fss.ru/FSS_TEST_CERT_2021.cer
  2. Тестовый контур принимает тестовые сертификаты Vipnet http://testcert.infotecs.ru/ . Был какой-то период, что они удалили на тестовом контуре сертификат УЦ из доверенных и отбраковывали тестовые сертификаты по "ошибка построения цепочки...".

Да, АРМ ЛПУ работает с тестовыми сертификатами. АРМ ФСС (подготовка расчетов для ФСС) получает от сервиса ошибку, в случае использования тестового сертификата: "Ошибка: ORA-20001: Некорректная подпись головной организации: Ошибка при проверке сертификата. VALID_SIGNATURE ЭП действительна; При проверке сертификата ЭП произошла ошибка. Ошибка построения цепочки сертификатов. Не найден сертификат Удостоверяющего Центра, указанный в сертификате пользователя". Либо АРМ ФСС игнорирует настройку "направление обмена" и работает только с рабочим контуром или тестовый контур не принимает тестовые сертификаты.

Я считаю что если шифрование работало в версии 1.1, то вам нужно написать в чат разработчиков ФСС в телеграмм (возможно там кто-то сталкивался с таким) и ваша проблема не имеет отношения к библиотеке GostCryptography

Единственный телеграмм канал ФСС, который я обнаружил - FSS_Info. Так там одни новости от ФСС и никакой технической информации. Подскажите, какой канал вы имели в виду?

@spiridonovav
Copy link
Author

Здравствуйте. Насколько я помню, ранее была проблема с использованием устаревшего ID. Возможно они изменили что-то в этой части.

Если использовать другой идентификатор, то от сервиса возвращается ошибка: "ru.fss.integration.ws.fault.v01.InternalException: Не удалось расшифровать сообщение. Возможно сообщение зашифровано на ключе отличном от ключа уполномоченного лица ФСС. Проверьте правильность и актуальность ключа уполномоченного лица ФСС."

@spiridonovav
Copy link
Author

Полный текст последнего варианта процедуры шифрования:

`var publicKeyFSS = (GostAsymmetricAlgorithm)fssCert.GetPublicKeyAlgorithm();
var element = (XmlElement)elements[0];
var header = request.GetElementsByTagName("Header", xmlsoapNamespace); ;
if (header.Count > 0)
{
var bsToken = request.CreateElement("", "X509Certificate", "http://www.w3.org/2000/09/xmldsig#");
bsToken.InnerText = Convert.ToBase64String(insCert.GetPublicKey());
//bsToken.InnerText = Convert.ToBase64String(insCert.RawData);
header[0].AppendChild(bsToken);
}
// Создание случайного сессионного ключа
using (var sessionKey = new Gost_28147_89_SymmetricAlgorithm())
{
// Шифрация элемента
var encryptedData = encryptedXml.EncryptData(element, sessionKey, false);

                // Шифрация сессионного ключа с использованием общего симметричного ключа
                var encryptedSessionKeyData = GostEncryptedXml.EncryptKey(sessionKey, publicKeyFSS);

                // Формирование элемента EncryptedData
                var elementEncryptedData = new EncryptedData();
                elementEncryptedData.Type = EncryptedXml.XmlEncElementContentUrl;
                //elementEncryptedData.Type = EncryptedXml.XmlEncElementUrl;
                elementEncryptedData.EncryptionMethod = new EncryptionMethod(sessionKey.AlgorithmName);
                elementEncryptedData.CipherData.CipherValue = encryptedData;
                elementEncryptedData.KeyInfo = new KeyInfo();

                // Формирование информации о зашифрованном сессионном ключе
                var encryptedSessionKey = new EncryptedKey();
                encryptedSessionKey.CipherData = new CipherData(encryptedSessionKeyData);
                //ФСС использует устаревший идентификатор
                //encryptedSessionKey.EncryptionMethod = new EncryptionMethod(publicKeyFSS.KeyExchangeAlgorithm);
                encryptedSessionKey.EncryptionMethod = new EncryptionMethod(GostCryptography.Gost_R3410.Gost_R3410_2001_AsymmetricAlgorithm.KeyExchangeAlgorithmValue);
                encryptedSessionKey.KeyInfo.AddClause(new KeyInfoX509Data(fssCert));

                // Добавление ссылки на зашифрованный ключ, используемый при шифровании данных
                elementEncryptedData.KeyInfo.AddClause(new KeyInfoEncryptedKey(encryptedSessionKey));

                var newDoc = new XmlDocument() { PreserveWhitespace = true };
                newDoc.LoadXml(SOAPMessageStr);

                // Замена элемента его зашифрованным представлением
                GostEncryptedXml.ReplaceElement((XmlElement)newDoc.GetElementsByTagName("Body", xmlsoapNamespace)[0], elementEncryptedData, true);

                return newDoc;
            }`

@spiridonovav
Copy link
Author

Возможно, ошибка ""ru.fss.integration.ws.fault.v01.InternalException: Error in execution of data encrypting/decrypting operation. class org.apache.xml.security.encryption.XMLEncryptionException.", возникает в сервисе ФСС уже на этапе шифрования ответного сообщения из-за того, что я "неправильно" передаю им свой сертификат?
Кто ни будь знает как нужно?

@spiridonovav
Copy link
Author

spiridonovav commented Jan 24, 2021

В спецификации написано:

  1. в разделе подписания сообщения: "В блоке soapenv:Header в подписанном запросе добавляется блок , который содержит публичный сертификат пользователя в формате x509v3 (кодировке base64)."
  2. в разделе шифрования сообщения: "В блоке soapenv:Header исходного шифруемого сообщения необходимо добавить блок , содержащий публичный ключ сертификата отправителя. Структура сообщения для шифрования после этого будет выглядеть следующим образом:"

Может нужно добавлять два сертификата? Тогда непонятно, что за сертификат "пользователя"? Сертификат "отправителя" - это, наверное, сертификат страхователя.

@spiridonovav
Copy link
Author

Все таки правильный вариант: bsToken.InnerText = Convert.ToBase64String(insCert.RawData);
Так получается идентичная строка элемента , что и при использовании: KeyInfoX509Data(insCert)

@spiridonovav
Copy link
Author

Моё зашифрованное сообщение выглядит так:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header/> <SOAP-ENV:Body> <EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns="http://www.w3.org/2001/04/xmlenc#"> <EncryptionMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gost28147"/> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#"> <EncryptionMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:transport-gost2001"/> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <X509Data> <X509Certificate></X509Certificate> </X509Data> </KeyInfo> <CipherData> <CipherValue></CipherValue> </CipherData> </EncryptedKey> </KeyInfo> <CipherData> <CipherValue></CipherValue> </CipherData> </EncryptedData> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

Еще я заметил отличие. В вашем примере атрибут Type имеет значение "http://www.w3.org/2001/04/xmlenc#Element". Хотя в документации в примерах указано "http://www.w3.org/2001/04/xmlenc#Content".
Но, в моем случае, это никак не влияет на результат.

@alexnur
Copy link

alexnur commented Jan 29, 2021

Добрый день! Я тоже уже несколько дней пробую получить ЭЛН (сервис страхователя) по спецификации 2.0.
Техподдержка ФСС не оказывает содействия в разработке, но на кое какие вопросы отвечает. Касаемо шифрования или примеров - не ответят. Проверено. Вот их почта: lk_test@fss.ru.
По спецификации 1.1 я без проблем шифрую запросы и дешифрую ответы от ФСС. С 2.0 - мог только подписать и отправить на тестовый контур без шифрования: https://docs-test.fss.ru/ws-insurer-v20_2/FileOperationsLnService?wsdl
Однако этот url уже несколько дней не доступен (404, not found). В поддержку сообщил, ответа пока не было.
Пробую также отправить на тестовый контур с шифрованием. Там в запросе ранее было getPrivateLNData, для 2.0 меняется на getPrivateLNDataRequest.
Возникает исключение при отправке запроса: 500 ошибка на стороне ФСС. У Вас хотя бы сообщение развернутое приходит. Запрашивал в поддержке тестовый готовый зашифрованный запрос, чтобы исключить остальные проблемы. Прислали зашифрованный запрос. Если я его отправляю на тестовый контур с шифрованием - все хорошо.
В перечне изменений некотоыре моменты не уточнены, помимо заголовка шифруемого сообщения. Лучше бы этого перечня изменений не было. Сбивает с толку. Если в перечне изменений чего-то нет, значит вещи не менялись. У них другое понимание.
В п.5.1. "Этапы шифрования сообщения", далее 2.1. Указан алгоритм трансформации "urn:ietf:params:xml:ns:cpxmlsec:algorithms:transport-gost2001", а в спецификации 1.1 "urn:ietf:params:xml:ns:cpxmlsec:algorithms:transport-gost2012". Однако в своей программе в версии 1.1, несмотря на то, что в спецификации указан 2012, у меня было указано именно "urn:ietf:params:xml:ns:cpxmlsec:algorithms:transport-gost2001", и все работало.
В общем, давайте вместе пробовать разбираться.
Вот мой код:
` // Спецификация 2.0
public class EncryptedXmlSessionKey2: EncryptedXmlSessionKey
{
#region Шифрование документа по спецификации 2.0.
///


/// Шифрование документа по спецификации 2.0.
///

/// Подписанный ЭЦП XML-документ.
/// var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
/// Публичный сертификат ФСС.
/// Публичный сертификат страхователя.
protected override XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, Gost_28147_89_SymmetricAlgorithmBase sharedKey,
X509Certificate2 certificateEncryption,
X509Certificate2 certificateOpen)
{
// Сюда будет записан зашифрованный XML-документ "xmlDocument".
XmlDocument result = new XmlDocument();
// Согласно спецификации 2.0 необходимо добавить X509Certificate (публичный сертификат пользователя) в header после подписания документа,
// но перед шифрованием.
// Несмотря на то, что этот же сертификат добавлен в header в секцию BinarySecurityToken!
InsertX509UserPublicCertificateToXmlHeader(xmlDocument, certificateOpen);
// Ищем заданный элемент для заширования. Envelope
XmlElement elementToEncrypt = GetElementToEncrypt(xmlDocument, ref result);
// Создаем объект EncryptedData и заполняем его необходимой информацией.
EncryptedData edElement = new EncryptedData();
//edElement.Type = EncryptedXml.XmlEncElementUrl;
edElement.Type = EncryptedXml.XmlEncElementContentUrl;
// Заполняем алгоритм зашифрования данных. Он будет использован при расшифровании.
edElement.EncryptionMethod = new EncryptionMethod(Gost_28147_89_SymmetricAlgorithm.AlgorithmNameValue);
// Создаем новую ссылку на ключ.
edElement.KeyInfo = new KeyInfo();
// Создаем случайный симметричный ключ.
// В целях безопасности удаляем ключ из памяти после использования.
using (Gost_28147_89_SymmetricAlgorithm sessionKey = new Gost_28147_89_SymmetricAlgorithm(sharedKey.ProviderType))
{
// Gost_R3410_2001_Constants.SignatureAlgorithm
//sessionKey.
//При генерации сессионного ключа 28147 всегда используется 2001 провайдер(TypeId = 75).
//Соответственно параметры CIPHER_OID ключа всегда берутся для указанного провайдера.
//И если при шифровании ключа используется новый сертификат ФСС(уполномоченного лица) с
//2012 ключом получается нехорошо:
// -(.
//В обернутом ключе параметры алгоритма прописываются
//1.2.643.2.2.31.1
//когда как ФСС ожидает
//1.2.643.7.1.2.5.1.1
// Создаем объект класса EncryptedXml
EncryptedXml eXml = new EncryptedXml();
// Зашифроваем узел на симметричном ключе.
byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, sessionKey, false);
// Зашифровываем сессионный ключ и добавляем эти зашифрованные данные к узлу EncryptedKey.
EncryptedKey ek = new EncryptedKey();
byte[] encryptedKey = GostEncryptedXml.EncryptKey(sessionKey, (GostAsymmetricAlgorithm)certificateEncryption.GetPublicKeyAlgorithm());
ek.CipherData = new CipherData(encryptedKey);
//ek.EncryptionMethod = new EncryptionMethod(GostEncryptedXml.XmlEncGostNamespaceUrl + "transport-gost2001");
ek.EncryptionMethod = new EncryptionMethod(GostCryptography.Gost_R3410.Gost_R3410_2001_AsymmetricAlgorithm.KeyExchangeAlgorithmValue);
KeyInfoX509Data data = new KeyInfoX509Data(certificateOpen);
ek.KeyInfo.AddClause(data);
// Добавляем ссылку на зашифрованный ключ к зашифрованным данным.
edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek));
// Добавляем зашифрованные данные к объекту EncryptedData.
edElement.CipherData.CipherValue = encryptedElement;

        }
        // Заменяем исходный узел на зашифрованный.
        EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);

        return result;
    }
    #endregion

    private void InsertX509UserPublicCertificateToXmlHeader(XmlDocument xmlDocument, X509Certificate2 certificateOpen)
    {
        XmlNode nodeHeader = xmlDocument.LastChild.ChildNodes[1];
        XmlElement el = xmlDocument.DocumentElement;
        XmlElement elemX509Certificate = xmlDocument.CreateElement("X509Certificate");
        XmlText certX509xmlText = xmlDocument.CreateTextNode(Convert.ToBase64String(certificateOpen.Export(X509ContentType.Cert),
            Base64FormattingOptions.InsertLineBreaks));
        elemX509Certificate.AppendChild(certX509xmlText);
        nodeHeader.AppendChild(elemX509Certificate);
    }

    #region Приватный метод. Получение части XML-документа, которую необходимо зашифровать ("Envelope").
    /// <summary>
    ///  Получение части XML-документа, которую необходимо зашифровать ("Envelope").
    /// </summary>
    /// <param name="xmlDocument"> Подписанный ЭЦП XML-документ. </param>
    /// <param name="xml"> Необходимо передать новый объект XmlDocument как ref. Часть документа ("Envelope") будет ссылаться на новый XML-документ "xml". 
    /// Именно документ "xml" после дальнейшей обработки необходимо будет отправить как зашифрованный.</param>
    protected override XmlElement GetElementToEncrypt(XmlDocument document, ref XmlDocument xml)
    {
        document.PreserveWhitespace = true;
        XmlNode elementBody = document.GetElementsByTagName("Envelope", MyConst.xmlns_soapenv)[0];
        // Создаем новый XML документ.
        XmlDocument doc = new XmlDocument();
        //XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);

        //ns.AddNamespace("soapenv", MyConst.xmlns_soapenv);
        //ns.AddNamespace("xenc", MyConst.xmlns_xenc);
        //ns.AddNamespace("ds", MyConst.xmlns_ds);
        //ns.AddNamespace("sch", MyConst.xmlns_sch);
        //ns.AddNamespace("wsse", MyConst.xmlns_wsse);
        //ns.AddNamespace("wsu", MyConst.xmlns_wsu);

        MemoryStream newRequestStream = new MemoryStream();
        XmlWriter writer = XmlWriter.Create(newRequestStream, new XmlWriterSettings { Encoding = Encoding.UTF8 });
        writer.WriteStartDocument();
        // Envelope 
        writer.WriteStartElement("soapenv", "Envelope", MyConst.xmlns_soapenv);
        //Header 
        writer.WriteStartElement("soapenv", "Header", MyConst.xmlns_soapenv);
        writer.WriteEndElement(); // Header
        writer.WriteStartElement("soapenv", "Body", MyConst.xmlns_soapenv); // Body
        // ************************************************************* EncryptedData ************************************************************************** /
        writer.WriteRaw(elementBody.OuterXml);
        // ******************************************************************************************************************************************************* /
        writer.WriteEndElement(); // Body
        writer.WriteEndElement(); // Envelope
        writer.WriteEndDocument();
        writer.Flush();
        string xmlText = Encoding.GetEncoding("UTF-8").GetString(newRequestStream.ToArray());

      //  xmlText = xmlText.Replace("<?xml version=\"1.0\" encoding=\"utf-8\"?>", "");

        newRequestStream.Position = 0;
        xml.Load(newRequestStream);
        writer.Close();
        // Ищем заданный элемент для зашифрования. Envelope
        XmlElement elementToEncrypt = xml.GetElementsByTagName("Envelope", MyConst.xmlns_soapenv)[1] as XmlElement;

        return elementToEncrypt;
    }
    #endregion
}`

@alexnur
Copy link

alexnur commented Jan 29, 2021

Кстати, когда пробую дешифровать зашифрованный ответ ФСС (после отправки им зашифрованного запроса, который они прислали мне по почте), то получаю исключение "Плохие данные". Дешифровать пробую как и для спецификации 1.1.
Исключение возникает при возврате результата из метода
return GostEncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, myKey);
Исключение: 'System.Security.Cryptography.CryptographicException' in GostCryptography.dll ("Плохие данные.
")

` private static SymmetricAlgorithm GetDecryptionKey(EncryptedData encryptedData, X509Certificate2 myCert)
{
IEnumerator encryptedKeyEnumerator = encryptedData.KeyInfo.GetEnumerator();
// Проходим по всем KeyInfo
while (encryptedKeyEnumerator.MoveNext())
{
// пропускам все что неизвестно.
KeyInfoEncryptedKey current = encryptedKeyEnumerator.Current as KeyInfoEncryptedKey;
if (current == null) continue;
// до первого EncryptedKey
EncryptedKey encryptedKey = current.EncryptedKey;

            if (encryptedKey == null)
                continue;
            KeyInfo keyinfo = encryptedKey.KeyInfo;
            // Проходим по всем KeyInfo зашифрования ключа.
            IEnumerator srcKeyEnumerator = keyinfo.GetEnumerator();
            while (srcKeyEnumerator.MoveNext())
            {
                // пропускам все что неизвестно.
                KeyInfoX509Data keyInfoCert = srcKeyEnumerator.Current
                    as KeyInfoX509Data;
                if (keyInfoCert == null)
                    continue;
                var keyContainer = myCert.GetPrivateKeyInfo();
                // Приватный ключ, открытый ключ которого мы отправляли при шифровании запроса
                Gost_R3410_2012_256_AsymmetricAlgorithm dd = new Gost_R3410_2012_256_AsymmetricAlgorithm(ProviderType.CryptoPro_2012_512);

                var privateKey = new Gost_R3410_2012_256_AsymmetricAlgorithm(keyContainer);
                // Приватный ключ, открытый ключ которого мы отправляли при шифровании запроса
                Gost_R3410_2012_256_AsymmetricAlgorithm myKey = privateKey as Gost_R3410_2012_256_AsymmetricAlgorithm;
                if (myKey == null)
                    continue;

                return GostEncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, myKey);
            }
        }
        return null;
    }`

@spiridonovav
Copy link
Author

Добрый день.

"Плохие данные.

Такое исключение, насколько я помню, возникает в случае, если в настройках GostCryptography Криптопровайдер не соответствует, указанному в сертификате.
Смотрю ваш код. Может общими усилиями разберемся.

@spiridonovav
Copy link
Author

Кстати, когда пробую дешифровать зашифрованный ответ ФСС (после отправки им зашифрованного запроса, который они прислали мне по почте), то получаю исключение "Плохие данные"

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

@spiridonovav
Copy link
Author

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

Интереснее было бы получить от ФСС и подписанное сообщение и его зашифрованный вариант. В запросе ЭЛН нет никаких закрытых данных. Они вполне могут предоставить эти данные. Можете у них запросить?
На всякий случай можете выложить зашифрованный запрос, полученный от ФСС?

@spiridonovav
Copy link
Author

byte[] encryptedKey = GostEncryptedXml.EncryptKey(sessionKey, (GostAsymmetricAlgorithm)certificateEncryption.GetPublicKeyAlgorithm());

Не понятно, почему вы шифруете ключ на сертификате страхователя, а не на сертификате ФСС?
Вообще не понял, почему у метода EncryptXmlDocument так много параметров-сертифкатов?
Нужен ведь сертификат страхователя и сертификат ФСС. Или я ошибаюсь?

@alexnur
Copy link

alexnur commented Jan 29, 2021

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

Интереснее было бы получить от ФСС и подписанное сообщение и его зашифрованный вариант. В запросе ЭЛН нет никаких закрытых данных. Они вполне могут предоставить эти данные. Можете у них запросить?
На всякий случай можете выложить зашифрованный запрос, полученный от ФСС?

Ну да. Они ответ шифровать будут публичным сертификатом страхователя, т.е. в предоставленном ими же зашифрованном запросе указан ихний публичный сертификат (не уполномоченного лица ФСС). В понедельник выложу зашифрованный запрос рабочий. Запросить могу подписанное сообщение и зашифрованное, но нам это мало чем поможет. Ведь у нас получается отправить на сервис с подписанием (который сейчас не доступен). Отвечают они долго. Некоторые письма игнорируют. Вообще такое ощущение что там разные люди отвечают, они не представляются.

@alexnur
Copy link

alexnur commented Jan 29, 2021

byte[] encryptedKey = GostEncryptedXml.EncryptKey(sessionKey, (GostAsymmetricAlgorithm)certificateEncryption.GetPublicKeyAlgorithm());

Не понятно, почему вы шифруете ключ на сертификате страхователя, а не на сертификате ФСС?

certificateEncryption - Это сертификат ФСС. Форматирование кода тут сломалось вместе с директивами region. Но порядок сохранился для сигнатуры метода:
protected override XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, Gost_28147_89_SymmetricAlgorithmBase sharedKey,
X509Certificate2 certificateEncryption,
X509Certificate2 certificateOpen)

/// Публичный сертификат ФСС.
/// Публичный сертификат страхователя.

Вообще не понял, почему у метода EncryptXmlDocument так много параметров-сертифкатов?
Нужен ведь сертификат страхователя и сертификат ФСС. Или я ошибаюсь?

Я брал готовый пример, переделывал. С какой целью переделывал - уже не помню. Параметров на самом деле не много

  • сам xml документ, подлежащий шифрованию;
  • sharedKey - отправляем в зависимости от провайдера (КриптоПро/VipNet), до вызова метода;
  • сертификат ФСС;
  • сертификат страхователя.
    Сертификатом ФСС шифруем (расшифровать сможет только владелец закрытого ключа, т.е. только ФСС).
    Сертификат страхователя необходимо приложить в 2 местах: keyInfo и в X509Certificate в header'е. Наверное он им нужен с целью проверки цепочки сертификатов при проверке ЭЦП страхователя и шифрования ответа. Почему раньше обходились при шифровании запрса только указанием в keyInfo, а теперь до шифрования потребовалось еще и в X509Certficate указать - без понятия. Можно ведь для 2 целей как и прежде публичный сертификат страхователя из keyInfo брать.

@alexnur
Copy link

alexnur commented Feb 1, 2021

Выкладываю зашифрованный запрос. Зашифрован тестовым сертификатом ФСС для ЭЛН 2021 года. Параллельно дублирую на файлообменнике: https://dropmefiles.com/jQxmK

Адрес тестового сервиса ЭЛН с шифрованием для страхователя
https://docs-test.fss.ru/ws-insurer-crypto-v20/FileOperationsLnService?WSDL

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><SOAP-ENV:Body><xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Type="http://www.w3.org/2001/04/xmlenc#Element"><xenc:EncryptionMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gost28147"/><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"><xenc:EncryptionMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:transport-gost2001"/><ds:KeyInfo> <ds:X509Data> <ds:X509Certificate>MIIIyTCCCHSgAwIBAgIQAdaQCGAJoDAAAAKLA+gAAjAMBggqhQMHAQEDAgUAMIIB2DEYMBYGBSqF A2QBEg0xMDI3NzM5NDQzMjM2MT0wOwYDVQQJDDTQntGA0LvQuNC60L7QsiDQv9C10YDQtdGD0LvQ vtC6LCDQtC4gMywg0LrQvtGA0L8uINCQMRowGAYIKoUDA4EDAQESDDAwNzczNjA1NjY0NzELMAkG A1UEBhMCUlUxGTAXBgNVBAcMENCzLiDQnNC+0YHQutCy0LAxGDAWBgNVBAgMDzc3INCc0L7RgdC6 0LLQsDEdMBsGCSqGSIb3DQEJARYOaW5mby11Y0Bmc3MucnUxZzBlBgNVBAoMXtCk0L7QvdC0INGB 0L7RhtC40LDQu9GM0L3QvtCz0L4g0YHRgtGA0LDRhdC+0LLQsNC90LjRjyDQoNC+0YHRgdC40LnR gdC60L7QuSDQpNC10LTQtdGA0LDRhtC40LgxLjAsBgNVBAsMJdCm0LXQvdGC0YDQsNC70YzQvdGL 0Lkg0LDQv9C/0LDRgNCw0YIxZzBlBgNVBAMMXtCk0L7QvdC0INGB0L7RhtC40LDQu9GM0L3QvtCz 0L4g0YHRgtGA0LDRhdC+0LLQsNC90LjRjyDQoNC+0YHRgdC40LnRgdC60L7QuSDQpNC10LTQtdGA 0LDRhtC40LgwHhcNMjAwOTIxMTExNDAwWhcNMjEwOTIxMTExNDAwWjCCAbExGjAYBggqhQMDgQMB ARIMMDA3NzM2MDU2NjQ3MRgwFgYFKoUDZAESDTEwMjc3Mzk0NDMyMzYxLjAsBgNVBAsMJdCm0LXQ vdGC0YDQsNC70YzQvdGL0Lkg0LDQv9C/0LDRgNCw0YIxZzBlBgNVBAoMXtCk0L7QvdC0INGB0L7R htC40LDQu9GM0L3QvtCz0L4g0YHRgtGA0LDRhdC+0LLQsNC90LjRjyDQoNC+0YHRgdC40LnRgdC6 0L7QuSDQpNC10LTQtdGA0LDRhtC40LgxNTAzBgNVBAkMLNCe0YDQu9C40LrQvtCyINC/0LXRgNC1 0YPQu9C+0LosINC00L7QvCAzINCQMRkwFwYDVQQHDBDQsy4g0JzQvtGB0LrQstCwMRgwFgYDVQQI DA83NyDQnNC+0YHQutCy0LAxCzAJBgNVBAYTAlJVMWcwZQYDVQQDDF7QpNC+0L3QtCDRgdC+0YbQ uNCw0LvRjNC90L7Qs9C+INGB0YLRgNCw0YXQvtCy0LDQvdC40Y8g0KDQvtGB0YHQuNC50YHQutC+ 0Lkg0KTQtdC00LXRgNCw0YbQuNC4MGYwHwYIKoUDBwEBAQEwEwYHKoUDAgIkAAYIKoUDBwEBAgID QwAEQPvJJ0+TWO6eZmUfseZRd6PJ3y++tKoA5WPBNI6wzkWnGndCGd6pqSzh7QW3nthnxvaT57w/ q9h8HiLOWFTY2YmBCQAwM0U4MDAwMqOCBCcwggQjMA4GA1UdDwEB/wQEAwID2DAdBgNVHSUEFjAU BggrBgEFBQcDAgYIKwYBBQUHAwQwJwYDVR0gBCAwHjAIBgYqhQNkcQEwCAYGKoUDZHECMAgGBiqF A2RxAzAyBgUqhQNkbwQpDCfQmtGA0LjQv9GC0L7Qn9GA0L4gQ1NQINCy0LXRgNGB0LjRjyA0LjAw ggHLBgUqhQNkcASCAcAwggG8DIGZ0KHRgNC10LTRgdGC0LLQviDQutGA0LjQv9GC0L7Qs9GA0LDR hNC40YfQtdGB0LrQvtC5INC30LDRidC40YLRiyDQuNC90YTQvtGA0LzQsNGG0LjQuCAo0KHQmtCX 0JgpICJWaVBOZXQgQ1NQIDQuMiIgKNCy0LDRgNC40LDQvdGCINC40YHQv9C+0LvQvdC10L3QuNGP IDMpDFrQn9GA0L7Qs9GA0LDQvNC80L3Ri9C5INC60L7QvNC/0LvQtdC60YEgIlZpUE5ldCDQo9C0 0L7RgdGC0L7QstC10YDRj9GO0YnQuNC5INGG0LXQvdGC0YAgNCIMXNCX0LDQutC70Y7Rh9C10L3Q uNC1INC+INGB0L7QvtGC0LLQtdGC0YHRgtCy0LjQuCDihJYgMTQ5LzMvMi8yLTIwNTIg0L7RgiAy OS4wMS4yMDE0INCz0L7QtNCwDGTQodC10YDRgtC40YTQuNC60LDRgiDRgdC+0L7RgtCy0LXRgtGB 0YLQstC40Y8g4oSWINCh0KQvMTI4LTI5MzIg0L7RgiAxMCDQsNCy0LPRg9GB0YLQsCAyMDE2INCz 0L7QtNCwMAwGA1UdEwEB/wQCMAAwNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2Zzcy5ydS91Yy9H VUNfRlNTX1JGXzIwMjAuY3JsMIIBYAYDVR0jBIIBVzCCAVOAFD2o7bwXrstz2cPo0cin9ryscFZm oYIBLKSCASgwggEkMR4wHAYJKoZIhvcNAQkBFg9kaXRAbWluc3Z5YXoucnUxCzAJBgNVBAYTAlJV MRgwFgYDVQQIDA83NyDQnNC+0YHQutCy0LAxGTAXBgNVBAcMENCzLiDQnNC+0YHQutCy0LAxLjAs BgNVBAkMJdGD0LvQuNGG0LAg0KLQstC10YDRgdC60LDRjywg0LTQvtC8IDcxLDAqBgNVBAoMI9Cc 0LjQvdC60L7QvNGB0LLRj9C30Ywg0KDQvtGB0YHQuNC4MRgwFgYFKoUDZAESDTEwNDc3MDIwMjY3 MDExGjAYBggqhQMDgQMBARIMMDA3NzEwNDc0Mzc1MSwwKgYDVQQDDCPQnNC40L3QutC+0LzRgdCy 0Y/Qt9GMINCg0L7RgdGB0LjQuIILAKhAVEAAAAAAA58wHQYDVR0OBBYEFBGLbUHNNZEst5g5AfDd 9w6rG2H5MAwGCCqFAwcBAQMCBQADQQDVak5Yshj5IiR0tMqBmPfvVF3SMB/sw6k8qnRwubcePmPF X+VU7vbTLYeSDT82mUC4kXios9LQDpThFlpQrbIn</ds:X509Certificate> </ds:X509Data> </ds:KeyInfo><xenc:CipherData><xenc:CipherValue>MIGpMCgEIPMiLrXgZaMlkSsom/LuHvGTMezcCbDx5/oCFKQvFB7QBAQ/qlDpoH0GCSqFAwcBAgUB AaBmMB8GCCqFAwcBAQEBMBMGByqFAwICJAAGCCqFAwcBAQICA0MABEC1Lt6OvjR8dvdFVHYf2fjP cT4xRAibFz9QReBwTrX4pjj1e6P3i0aUqGVkg4eYzSkyo9GQ5SN2xqOHwebzhgTsBAjTAf307w2I Jg==</xenc:CipherValue></xenc:CipherData></xenc:EncryptedKey></ds:KeyInfo><xenc:CipherData><xenc:CipherValue>zcozvg1rBwQhasrxS3fpgapDCgun2eJc29MNY7vfMd28L+fF4ZppO9QGMJ5PVT3eZJ2QRaOTOoIK TtRXtPZFzvTz0HHVT/LMz9Np6KFxiv9bsx7qcOZc8kYYOGPXZAS2CY1Bq6cXSdWc/Maw3o/8WwU3 u/d4cRShVqUL+tXTcdAaKGDiwYH76fbvT+3Wg5OMaJKcU1REXEV8dSJYGPUYGwYgc6THZ0OdB1JF yFBzdtsfLtbrE74t51teOiBX/Xk4g5UZZq4rYA9VWHTbFK4VodmYAe841NU0UgOwmQvDfr+zDItf lnpISF/BXOo81XpmDig7fQfAf9QiI3TLxNHpm7vfy9NT3j93OXxwIop+orwyNQm23LxsT4LZI5tB Q1fL7lsnFleyDZkWRZqe7je7XEwEPJkuTnPN0fQNMSaXvPG0xrTUD6/vBPRBSfLrbhbZcWeRq+3S EH9Jl1x14zU2mZFFuQcGGNVWkTr6ML6WOmniO3BSZ0ToAqgXivbV61lzFO8CAFbmUkPzJX5xgDhk 4qdv3U8QnkVlOBYh9ypmlKErLVs4IdHP9iWkGuKscYkTZXdnB6PXdNlnRLa/CvEf6mGdiW1eoLtT m31K6IrWgpaAD4v7KfefsK5UqSNGlUAQXSzO5bd3+A/6IGwuLKBId0O+GPgkAVDJvzjqFyrNGHGe Lb6qPX4FGW+YJihRekmva/uv9rjKl7nplpuSI/ZAeJFSI5Q4p8dXcZMrZ0mbr2MDKR5Cs6tQ1G7D 4rdBYCiu1k9FYlB3xNtGn/xhnnjeL4Um36X/OaHkJtZU0pQdAwxrBntVjdYsH8DPEdZLIWigzHWK rN8DPYcg4EGvMvFVSc9VZV3KnChgUJ4yBIWvm4YM+nn0naSifhuc/jN8mKxELL3npW86bObKJOTZ 4kgbTNGPT0Kk36JVfkjwlotw9PXxJiGA/TsAxz2L6J5XXTRSrfzKfwY5DGvi8Ofv+oIb+JDEkUZg l9iDegQlZk1wkJPpISmian6UHOv/pfsd03I/GgyXc2yHcu9+yAIEvHW0d2dlyoStLc7abVqqIM5j BN6lfER3d/bogs06wcduyz4sv+ZfdDUW43JgfEnvK3nNyzkKdzs/sWJcAx8y2RtZlDNSZEGuNdV5 ObhI8MW1D65BZE1cRJLXSr+KQ6wu3yq2ozao21RRSR7mE2U5GKjpwmJsHnmfj+nOxk+25ca4Jbml y3lwy2O1z5NiytLry8F9R7ZIhsfJPq8H3SAqZDYoFDGj66spb7o4pLG8GKdifJc2DT7ILcURITi9 oWiCLT9/1ro4nTxqzpHeyiUbP9wah2uU4577hEeKING7aHCukBKwqj1phoV1s0efOAlpK70wmhof pKJ1bdA4wx6fm4mGeOLzMUZClaeCd0I3nuwXG0L/kdXVAlMX8YVlhan74Q6BAaqcRg/LjUItBrZD qM2UoGHOAzxK3rT3nZm4lFBTnfq3Cp916KDshYZKlRZERHMFozFBYXOL1AYSX3W8oGJRP0hVfLvr 9l30ETsW+sD6mrx0LBvJhBnwUgK8uDnLYXtYtP2WkxVupf6FS5ppPbdilrEwj9bMTn4F/kq1AiHN /g1YaPUtU+tZKqzRf3LWClp3aCLRYfOurgcQo+Ph0NqgOMRI0MRD2+5U80oHhkdKHIeVtYNLMgA1 bvzKUHWTCh4y5TPgoo4OZf9egauQLndzuzhtK19Iq5a6YsNq34CyhE9Yz0Oy6KmUkW4WkQAqpoiH qxWDIBYE9SQ2l9OTn7VNBNB/h8sideIiOpSIwADPDTPuJjwpyyIiWb16puhB/UiH8M0FyKcLJ3Rb 39AwPKIA44kRVrnRLnVGwn1C4gazfwM+0MSFhSz9KLRJMsBcLbaEIEFXR8YK9I2KpChZ2lrev8kM VJNGm/QogaozmtR/YRMkZGDpoWbOaoezte3CX0oWi/4WZ4FNgrYS/IFJSOygWMsAHHrpk9zSS6hf itwAxv24yZC+jQnWoHPi4Ju0EIhn9KlHnilA1Sr0RuohH93LAImJvpQ7eTHFQHE9Fxde7zsk27+4 ZGY+8qkgECSsPldbbST4NIsidL63vS4QxlEtlWItJdVhkx4ktqcU2ZdPPcfGElrihnirDwk8nEc2 oquLg5PBT5lBuBqCxtB5MM42UnDIPuM5/Brqqv1Zc1ztOKZ3x7/REHwIAS4Hrb/NHhQhdwSIOk+6 Rpi6S9L5yHZlDnyN0k2EL56Noe79z/VHCkSngvSpV2/pFuzbiD23MW5DIwunhK/dXDUTLUCCmK/i GNWCyTgHwaQMT+WnNna7237ASZx09I0aaAnZ8BkR5awNdXpE62juRujHj61Mmyv3gNjvWvQZQi8W 4SizsiEk6U6875UgXshjCH/7QZYwPXIeKs3lrpZ/zFawbKsK5QuSnfoZSl5s9FXOi6sUX/mJdjP4 65NS/E9XLUywOcw5IztbplFTUcnvzCGZmLvoQwTE2pzDK4mChXrc+6Gw3pWTD+EYZ9db1XTVqZuj J0VMPm4H9u20YSpsCcW6hT15XZD5bgG2P8jlubDhtsA7jpI6YK9ytJIjPKoBTVLBFj5VyGW9+rhV hgaueE8i6Hku+TwcKWStQZgOgV2crB+wGVVeMhZr7Fa/qpBUh6hYpJpWxzwZVbtEM6G0yFO8ZSLz kpX4c21sRoRYfadMdr5iJ66n2x1Ym8iN/PuaKvw7NIQAcLO+MvZkmvyb3jKKEvlYgGYBO5Up+VKo 6jSS2uH6Nt3lAmVGh2bL/L6WXzcS7l8B9ktbf9EZNWLy7MSOhRbhbgyEYmZQbeQJjVR1H75CkTfa G1LpMIRp8T2f3B8+3WPjtB/UsHobntg52CjeBwbc+IuIAzlmVyeBq0lyp2YmZJwMlPt7sopguSK+ cWRuxROE9fZkL+gCbriZVXT1lgUw8i7lHLIkZ0JjIy4c1uC0L3zhIiu1KHwlovmrxCT7h/kRUT7S Fe0S+1m3AKYvSct8p16dFhWG+MHQaWLpPLo2EI2ak7BJxKlP5tGECnsMRlOfMIHsMBGDoNgS7mNq 0szICHF1wx+JlcmG9BZZ8n/rIm1puOEiEE5ideMXL/8Xziw8lTIy6BM2MOG7jjrLg3OUFrqvMJnl O7U3V+goUR/ofevbJa7EM9tz24Rwkq2b0MjkCKenUCsy1vzCfEG2S2mKvz/7jSWbjvw31blxx+M0 vwx/WqkE1J7ZXGu0YJyIvVr/aypv1mZCsq6pxRaqEJ8CwYL6UUjFlfo3lilpyHgyPPJ8DwB2DZ1B XKcdQ5mUyqctlY2cfwwuTMN93BuWAUTNojUFMp5U7ZXIrvj8/zj+xqLfinLVb+dbjVuqehvVXrkx gM8wuAzmYaCGdAdakttzRvdlAUGzWMO919AxNthEqVaYmEClgSGVayRokiHI0pGAOf+Jt9TuOe2j pb+TE/lf83gB71tZ6HmL1qh9yMZiLN2E5SOBwzk3z/P81OIIZ3HfhCtjPhKw6C3w4kzkY4yvuVDR OtnQbd+YFhax6gGO6XkR5+TS22XbprHiVlQ4o0CxR30maG3SLGfhwV7oulrMy+CMgO1j90ibMYhr q4OqkM4IGVAFFcH31PtXCL/gOBBThgxE+42uNH21MYvK6jT+5cUC1HTRRVI1G2PtNbrCd6tNUnip f2kbjrtyFoJ9ge2DIAMR3Ot6ZnzMg2EIR0RMQJBy2aSJu6x6nk2QaNZytJTfTiyo3Kcbtice+cWT 4RJ0Xkqm0yJrmZ3gEeTUjEKqYNwnUvWlvH+6kzA7dNFZMStjH+tP7MkU+Hl4VKzPZ/tazWl9SECF K0Mjc8xOBmjEYL3Ad8lNKkXH4VOTvbQQ6CZ2oeQyzGjQbGbxsTq9978wYwvkH2imHo6ZqVih88HI Q2gnwdh1rBaHoV+5t0N4gd0kDM4PeC2IhJ/6fBd/zRVh+++lqQWdyS9dmVBxJkCj3BTgXQU9IKG6 OE4tbq3/LJP9EZL86JAjsMm21OV2nOoGZqE++7d8yp0Y9SKkdvi1Y7PT+AforQ+Vn7q5wx3MFOBK yeNoybyq821wbmHXLJN9oqeg+QAYDZzfbmGnU84t8ZAp4QjJgKkK7lQRGSvptTc57Bx6QpUcgTIe Zca2pn28veEkj7AbBCvUb+9y9IYx2r1b37l07lfmqj215Tzshc2/11TX5oSZ+Q52pKNK6PV0aR37 n3T1m4eiEqc9I2JwVORcysphTYjagF2W/3r3fcG+RQRsr7HZAmzZhMsG78JXCAMTvh+Si7QjkG3U a0afM2QcWG/GcQjG4XBQKa6wZh9CBDq+Qii+i9EEXFntDCQutlkorVj+zFEdCoC0T6nc+fgoYdeQ 0bK0OUl85ItpXgGuvpIRhzPS+l+mPVvkif35pgoXaSHT+Y7PO9IAb8078dU91OOg6hBwLb1ArDGZ eZ9XUwWPw6kIexTy7KcdkEChtmt+qkxycLcxK+itgwP7+UwxjzO/8ez8LXNKOZazhtpKGbsiDwtM MDleVUnHVb2H/P6Fod/KqMoCQGOLi3dxHR19PmnnSGAwKv9BOfbS9cvEkZ7aXPsdUAQNkEznJM2y vYGI3z6uFQOvhZTG4y9OJ7seK+3FOGuMukJKEGVsVcYH/CxyQMiWr7eqbFtKtwzEE1pWZkSzF9H3 S/DCN0Lulf7byz8ovHH3R0OlKxL2aDPOcjUUYSL5IIcLJePdGiz+gHe4uJ+lFiBCRAXZ02cfYISr pH/3QXqv2/Rlu8MzAZD5ug+UO8hFBj7+H0J/CfblmRjFyu1nYsrcl8iq+k33JD8I6UUqMhW5ob4l Hh5K2YbHjOmPpAILcPzmmjvbDImb+FDdm470kEP+fDTEBsIe3MiRdEakp5XY8zL9ruCqFX36hfT+ P44ZaW1jrhaze1c1QA77USJAWmfjfhsT5d8qqx9cmMvQLx9su5wM+a+dI8Dl9K82NTX7jaWBI3CK rK1g7V1uI0wNm5RdpKHxp72iEcdvhMMGZsA49Yn1dCgCZT5ilYd3zLZlPvdSkiOuNOnMHl5AxCZR mknT5Y75KhDV2e+C0wTjpaKGwmwoRPtnFKhz2Zl6U8ZdQv5SgExQt2bOwLMgTw5Rtxgl5XGDtW6S SqctW6TExBx74uN1q8NPDE87Gaif6qDy7YStrzMZGKxA8m3eM/X3sToYd+1hlAsJczKJAemdnxxW eP0P/ggivK0WgYzGKZugiL7klJYDZ2X6nLAyGpuFkEB3ZTqi/QtYnrjo58t4EPJ8mHqPULQ6rROA pNjaYo/7xyMIvoBngFOrIg1MwmLAb6HX4FM0DQC7PlmRSu/gHqK6ONgji2kHbxVbyCx/mHCPTVKb 1trCnmTsG4ax5tRREAS8i1+y4TFsCnbrvzJsaZUXna4SL5bRDj3yJFQx5egsYpe+hMI+/KNL6Vxo aPHdKhMbCL2dbXv4w9q77aeiC96MmP98lJuf30bvJjZrUmCgL2QfO5YA8GR49tWUW/Cucs/TpfgC ztpZFh8lPsHnta8RdcuAZx3ldWnrkBvnvM5vwO2i9rQtdI9Zk5QpRaVzSBX204kGLd/iF43NLn6j ZTWb3n59l89YEsLlqMsTLv97RwpX/H5pd2Fgoc/gIVh5HbCbi8LBxvbgydk9il39FEqMLT3AFpoG xCd+DYgqmcWZOK7OmPLGPtUdGAfPwjpqpHh70IKjNU2mXfZIaoTWnC9GK5ha0XeCwdtj3maVZ4fS YrDsWiCNjl1IIDh7LG/qIsXc6AT/iQANNFGU1zMW9Lz8XUPW8HkBRnk2o3BRvwWFgGIPEZKX9L26 vMrPOaBJdjGwqUk3IHSItZ0X5I+GfD5dnEuScaI2biyI5wa6j9JkkgSRrzR8jGbJ+c0BcayifXoM Vu1XmNj0R4GN0AELJShmptLa/Fcfx2sk5Yokt6JBjqtDFfcH/UokRPwlx1tQ1Wydy+vdkiqg/9CM s9VkbUbzvXNPTypn+MUcMlGw4KkBssCkMoSDIO4ftWCCnKAt4VqQ1rl5UmKH0zS/j32t84Bh7woA TTkGuwWeCeofmUpX+/pdudEet6YZPBN77FtcMsjeGb/R+Ld5Jlfd0XCM2XjXDeLBZjttLJqlwZQZ 9KsfobvQhiJEqxtwl9m8Dsa9e/mSad+utejz02J3Lx0z6/3EhywL8XiX7daDFnSK71kNn/oidgSB ErPzG9/akK/OUqanBdZMcWLvXVCVDfEbq0Q4C9rB33tsFGbH9eUo41b0r5PYC7P68MExBr40jwcs uz+t4b8VsJ2L0PTScH+z2FDahlEYrMhPpH5kSgk/doF813SMqU7qI4/iIkDp0ctvYho6U9M3XOns B0zCIXM/hZsVgiGlovlOndfGQgoO6M8HWRBGnFyIqdIZ9m8VK18CiszzydYan8vVeNpCoinWNLgC eunJNLpKZU25s0XlqeWAV1HCTpVPRgxWa4ubvMCIHwwxMCpx+9W5RLisTL9XKvvI59q+hd4CZEq7 B6NcL0/GcxiZ4IJto1/NeOm/yr9JCKFCXXwyY3NlcBxqRLh/++88V5J/pjLOx8Xp8ntOgCIWzMWB mWLqFkbKmJua/VmqKrKmxbb+NkBW6voiQ3ywSHLOvVSovEjlsE+KP4eCVcmiW6mNJ2iFdvFPsryB QBkv+mEvVhPB4nYvPckOt0LrY1FjSELcl1X+qNsar03+GbZwyJ1rbmnZXQVs1iZfZKDjO+ss5J7q kY6GwMblOwKHxBf2SKbXG4ABepGGqkinAxZ7ujVQrpJ0/WS8T3RgUG8zg+fjUZ/u2Ub2ZViWsxV6 1X3tq/2jv7E+73yjVEgwVZ3X2uECtFxURNKZtyaeQgdMZBe1X7cFFS/DmgLt3MXHv3wpjnvH8pH7 +QL/ZghsLIeKIorcL/YeBIZcm0tfafBPpnL8oNzLv0zwZmGbBJkP6btEj2QOJPw/OQYZ9NcVsYMY uBcWurtqXbHzEautlurlncag1OH3SpYyn6tMjB7EtW8ufpZ/yyOj6ELu2eDuYbXPHcx0tQbTEx+b VM4ulrjylcDtQX+23LcmJEnss3M7rPbeg245CO6pVhntFuY+e+C/1oXghyPO6ulAGxeb4SggJuJJ 5mwTFJ6+gNYWRC3TFg4ul53vx1GeuJf8mujnx1V9+7yEhUoWqOGdaOHJ/zPvI/+XXIKEVa1PEAyo SGA9abSSDvTjWm/ONYsMGt5kjzcW8nt5HT+ktRqR5gVQB817tWWbG5V2zcDCgGqcOFlxGuPOXsvj St7PXQ7Zr2Gcv1az5qW+W4PWz45fIMcvBSBkNEfifx55ndXlYiEODo3x3cDhzbdVVlgn7/NUAxZO 7YnPRn6P+NmwQTQpRk3ZLNxUSc9svqfRNrtaWVmANOOIwhCJWSg5qAZpImQgpZo9GU777xX+vKV5 0j7RwMqxtPLTLvQRFbbXUKFTYAOMVlp5fPl+DTRRjVyelBZxTWnaLjt+k+pyZkl+QDJi5Fq3Bcds Je7hNnBy8UXJyNBdC+vPmDzdLs3KnAz2nngNDr0N5czXJjDVeSXy7eNMUnn5rWlpbc0PbFBwue9m DshAWZK3wk/P8LvvZCpElXIp/+5kapJ3fPyvg6jfjIDT0k7th4h1m6piPXJj6969U/tiF06tZGZf Pb+Oy/TG+YvYUcy0oNF6eSz6lfH/E+CpQ3isorQMBQtdsPeXpprGtfiDPKo4wKa5WEwt0JVQNoAO g9ig0lwaNV0U+Cy/O16NzhVb7DbD7k/ycXfUSgH6EJl744R2c6Eje7wMIMIw/ZzdkxtqucUx5uAf hTLXiomowVT4RT3RUfJQXkio22kkNFDC1bnO5W0waDWIyjaxmfBGzkbeCYN2S8utSoGdHb4x5ixO 3tKb3M274EG4gktMWan1jo1sOn3auswZTgDBkZKmQbeehdQUgCj3pJ1ISYliM4eYLH791G1FiNdc yjJcNS+YZKFpllJ4RaM6NO+WBA/h7SaBPgDNcT2ZfoLlsBYn2CI3OT1+zAVZrd14dmVCNt/nUM/f UFYcJpguy23z+g4qw/zgalFq4aThVnt0RD2LyvZmJ4ricUbL08jJHUQUHF70H41bs3NHC/SfvlEr ziVj+gRGkyHuhkGBh6eba0PDKlK6Rmd4g/vbVgFWrGb7dONdqVO9Dacgos89h3gH+tGlV0ctxRGG tYB3/j23ZU73EnZS86kke7d7iDD2p0zWhBzedaiJLdI985NdYQs1XdiMrvH/kubFd7ZBNbG9Vsim z1UDCUsVlQPfHbbqHn2GvGmyvTcYgSEPZVu6KiKpTaISTPaJzMaoOofdhcKq/XNxSZWfhggmDXKS uDfawsuhojL7LS0aAuWs7v5mAlHgcDFi9HhYIgMlkOvNoEFBKEqv6JlQT4YI4qnYD9vvbZwLmASC oybVf2F/52ol8UH9mq24kPLJ0SYrH0m+x3XWZ/xgV2969diNk9DVlsZX9Cizjp5k8a5XyqBiTpfp +tdrcsvPTf3dRjiOSyVo6mxdzlnnHVZzvujKoZv/tPqjJUKIMluoQd/oDd8qcDdpJNeWxhy4S0iN z34cv6GXsvlSRRq701D2PVKG5Juh3opupkpp0dS8yBnl4w902DcdauDpMhhUy0rmZ4MBytM4zIy1 2f9/6jZxr0JfEdEx0JEnU2f+0Lxgv9TBYr+eiy6LB/PL7JTbFvYAiYJtQLaeGfs1+N9dJgkZk3lK LRLZI6ZidEfi63bAwjHP5e2wfkxik7430H46Oy8HClRE+IjXZ6PPhOO5RSrahFroeJF7mQJp9uFk FypPhcJatdXbTmao+MTwb25sE+8bj29m+8LxUmm4MFYoqCNPeoMYZhxYwNhPsUaAqWDB5j9M5JF7 JJN+s2h4yvdZYpUfU2dnnSqCokWahCaM5zET+GucUwlZL1Gp0NRPNS1o7ZOp+q1wCZ7bS4bASPdm 6KO/iWpeSP36yMhhJ2ADAqX3U6Ya7UfBe8EkR8zirW67oqetc5ofO4HFfskFpwIqw7+XLORfcmRp cI8GicY1aNiX6alfMkQAIM8X1rNHA3sjBwW6h+rkbMSKWRUsth1eG/7Xc4C0Ezz0F+0J2PhSaT2x LVXYt5/UqI1u6J5Luvu2P3DUX4ZwldusK5LrGIkIDn2M5u05QtTJE3afxymdPypp4wPirIgakXM3 Da1j4u49zr7C6ds1QCeu2qNF2jzufnS3/YvImg/55MaC2M4RFuI8MOvihCFsRnIkl5TmCsudjOQ9 k8JF3q+Bh9vIwwWxsP+HPPlnqhHD9e9YifQCQaX5lX6Dg1MUbmkYFbIw47rFYIFK1k9xNnN0npTS nLGUny4P5BfYHw8/skchjmgVqNTuU9E7uXQ7ABbDGEkeeAGpcV6tZSVc22Sooz/RtGK3GEBDR+tM eMwW10rVaNjWnrR7UNfmJiIF2e/TYjS9sjVEt0EdoXClK46/vdux99n0B/dCzEDSZgnVaHT9aGHq KH7egsUlLc9TI4IJvdaqR4f0Zl5LqT90OxoOlaELrgZtrhVGYX2e+WxSuYy+d68mLBvyJ1QO/e4P n275w1hE5CQJA7VJrJ6TM4cFyIM+k50x2Oxk4cdo+Si251jdDr6BKRwoMBNDVobIL9d+ji0ICiNx 89mnr0ocE7bAYzjA+qGbxRA5Qgkamopms6u2CxSc+VDB0oRYDo/9HzGZeMfzim/+d8moD+PdlMFT mueOmWcctP6o55RxmKnwjqcH7pZ2kySL8owXPAtkSdK/MDKLBwnyLIwgntXr5ovw8qsA/qkiqC/6 N/B7kSenKe24kacXiDDtZSalJFUUK8+lIkHSIyEu0L73H0xMOIRA4jFNhU8M1jyTZklH+4NlLEDS OvsgLmdxpu+XxiqbsKC5OAV46GtvtPFXZjkk6mjVCtMpZUe4diD0sh/4V/rg/HqSooSnq+odBep5 Eez3SB8yhCV3NAKfwCFSooc0LOqYV5Rc5uuHJ2gouRkZnB8fgv4HRn2SxtFHH6GZ9khfNc0Qc8n3 z6aVKoWBtcLwu4a2vR2X9eNiNit2iNF8Yq3jt1OBMqkLb6ZnamdGA4dvXexFjwbz+qQHKQSLuaVB ZhuyT3t/d99KCIhBjyUAIFtvy1+qPvyzBSdCUfF0gAWokSnajKxbDU2h8eB/SwvIdWADM9yLghl6 Gz7wP6mIAoErIQ3iwDBzMeJuMyKufJ34JW7KyZX7BRa8+YA3cnmNy+fOnJLjRHcJruCbmJHR8XAB rSAhfNaOCxk+CAsE5cngpS4Tn1XtlhS0WyqJUeMNnccVfeQjdMFjMwCo+FaGLp6n9J4nJx3lEKWi 1hT+vpyEzsaICKjskDn/OIo42g/V+CNFRiu83suDi7HHMKob3CiWs/VESMNeEaogIps6GKFjOw2y 1gnLW0IehA8Y1wE45GjbY1d6c8k/H72++SUdBearjOT5bf6ebLyBh/xbOQtGyAsxwcSff8FlQpJF MQzz5EzECE7CYrEsLkSrWorQB5Tmz89jDBxPg7Q3gcnX1GIty4hhDbBjguCsX/JEmEcSlPjnzaT8 /20qklNsx+gIQK3vbwwNq0wsBIrMZGW5MkYyvcbOhrlJGz5/otc26nMOzI6JIcWoffgR20VcmohI zcjowdAB+7XN7J8iJVcKZ9UzOILYT1EYgJoUqBKkt0KPCa52KeL0JQFZT8AervEPg7P4gApMthZU muuFbnkwJVYnDvfGjGkH8pj0rw1jfh7hGjz8WKS0RmuMm5SZTby8ckab5NaII05gt0X6+uOy44sb Inp3Pi+kboRX4ulQ/d7YxX6yyHdzXxqxT9wKb+mIdnl0fl92Q/dNjbEo2I+KwvYYNKStMzF3o6zL odZTKVw3PGd0saQwI7+L3j5do7kAlO18UVy+YHWbJDii9fbeGyJv8bN0Jr2DtHNnxpAtWPQRB0eM QY6DQvIeOAJSC3xCH+Xo9IVPzZIcf9qckO3KSThvuZA3cXH4v0gOVOOmuYCyhitpNyL3ILhrEcu3 mrUD6hqBqfYzo5jLTgJpu6nArDtwXndArdwf1KgZc3d9epVzn+ayUW6Ej72M1DarGCYncSIYP8Ci 4FgmC6jrfGjlu+wZwka+Z4zJx8Bb7Ac7I82dH2b2XlWXb38S30feXH8+zrSOXwQ7uylxHzuvUy2u WTpnP/ENG6KKqjWwckDBl/mXxXgHc5e3y4QbMr0m8N6Vn+plubWBp1wpZ5Pe3DxZMb89GBQdI31F Vfa4XzifEqcFoz+8lv3zBn9znbBWoK0638b2UvbxUTrDoYPPV2PzIjUb+aOzSO6DytXpqkaA8y0h FK1z1WHHliy5F5xUgA835BGcQo4/mRG+2WNRbxh+FsiOYX7kD4DExiA0QwDDoM8LyJDCTiSMPX4b BTnEnbvhukNRos8hH5yfqJQdAVRhFMFyY0bKWnV30L1ybA1Nw1K68l7ISmfcVZdUtt79Dt0RSdx+ t8jOf7FZh4TM5TwCN7fTlphiESY0X4gStkSEG93DESph0TAguZWxjEcKFYillh4bpsMfjycUCR0M c6EnTpv3oWYo+2OkjdQDbomSR6MxUQaM7knk+1sU+1tdmkdLJh5aScUdPWa91OZL6AFjvT0pZU6n VXKHT7FKCyYRDPiI1ATTgwh0t/gT5sK6u2PfiiUZ6WBmvCX7F3YclzCKe471jsrTSIaqpDde5Obi Fc5G8CUuzDmY9UDBdI22wK4ZD9rpv6YHj3P+gY70y1SE2NRodh+g0TLbYLd1P1obl41GPZdN19vY Leout/Psql18xFL8VJ9kO8XdFEsKxmbEfsEkSPpoviBCPD0Gp2qVwtDoRce0ggOViU+W1RIaYPrn egzIH2IOmEZNraEg/6EnMEi9Bnny+NaM6NGcKlPtcVUt+rgDUj7Smdxo6dpZvw9w7XQK5Nd6cyZr ADqw6FxjPtERLZR6flTDhobvdc6RJXZ6LODdUBbcImG0JIfIC/RtyEIlRjUssx6Jg71vCJsG3sRz PmKIUoHvf8Mg0/8dyqUCZoht22s58pyjI1Mc2rGz7rH4ci+M0T/5Rltp4HhQL0LsnUYB87TYCVav s/WXWRgMXuRkuNokn2v4VIXbKHp8nLuRXDFsnn56aR54oBdxRppNofQfyT905uQXtO4yAzDsZlbU Z/Ehhu0mxmWMSrXAoq7qTn3gSQZqg2d+Mg0W7rXyLrG47x/rlkRrdIhJ4XZ5JTXS7Q==</xenc:CipherValue></xenc:CipherData></xenc:EncryptedData></SOAP-ENV:Body></SOAP-ENV:Envelope>

@alexnur
Copy link

alexnur commented Feb 3, 2021

На просьбу прислать тестовый запрос подписанный и зашифрованный получил следующий ответ:
"Кажется, что это бессмысленно, т.к. расшифровать запрос в обратную сторону все равно не получится.
Обратите внимание, в спецификации страхователя 2.0 описаны шаги по шифрованию запроса.
Также, если вы для работы своего ПО используете библиотеку шифрования GostCryptography, то она была переписана, прежняя версия не может корректно работать с сервисом 2.0."

У меня была GostCryptography версии 2.0.7, с которой работала спецификация 1.1.
В репозитории есть версия 2.0.8. Установил ее. Изменений никаких - ФСС по-прежнему не может расшифровать мой запрос. Запросы по спецификации 1.1 без проблем работают в том числе и с версией 2.0.7.
В АРМ ФСС используется GostCryptography вообще версии 2.0.2. Ее я тоже пробовал подключать к проекту. Изменений никаких.
Удивительно другое - согласно ответу ФСС требуется более новая версия, мол со старой работать не будет. А сами используют 2.0.2.
В общем, вопрос открыт.

@AlexMAS
Copy link
Owner

AlexMAS commented Feb 3, 2021

Большие переделки произошли с релизом 2.0, потом были правки мелких багов и косметические дополнения. :)

@spiridonovav
Copy link
Author

Также, если вы для работы своего ПО используете библиотеку шифрования GostCryptography, то она была переписана, прежняя версия не может корректно работать с сервисом 2.0."

Очень интересно! А что они такого могли сделать, что:

  1. Шифрование стало "несовместимым" с сервисом 1.1
  2. Спецификация на сервис 2.0 (в разделе шифрования) практически не отличается от спецификации 1.1.

Уважаемый @AlexMAS, вы не могли бы прокомментировать эти новые данные?

Ссылка на спецификацию сервиса 2.0 : https://cabinets-test.fss.ru/%D0%A1%D0%BF%D0%B5%D1%86%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%AD%D0%9B%D0%9D_%D0%A1%D1%82%D1%80%D0%B0%D1%85%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C_v_2_0_20210112.docx

@spiridonovav
Copy link
Author

В АРМ ФСС используется GostCryptography вообще версии 2.0.2. Ее я тоже пробовал подключать к проекту. Изменений никаких.
Удивительно другое - согласно ответу ФСС требуется более новая версия, мол со старой работать не будет. А сами используют 2.0.2.
В общем, вопрос открыт.

В АРМ ФСС использует фактически свой вариант GostCryptography. У них в ней свои классы, интерфейсы. Скорее всего у них не заморачиваются с изменением ее версии. В любом случае, у них своя библиотека и сравнивать ее версию с версией открытой библиотеки бесполезно.

@AlexMAS
Copy link
Owner

AlexMAS commented Feb 4, 2021

Да, скорей всего, у них свой fork, что усложняет ситуацию. Возможно, у них на это были свои причины.

@spiridonovav
Copy link
Author

spiridonovav commented Feb 4, 2021

Да, скорей всего, у них свой fork, что усложняет ситуацию. Возможно, у них на это были свои причины.

Но ведь в спецификации должны быть отражены ВСЕ требования?
Вы не могли бы предположить, что они могли изменить в сервисе, чтобы перестало расшифровываться сообщение.
Вот требования из спецификации сервиса 2.0:

5.1. Этапы шифрования сообщения

  1. Создание случайного сессионного ключа.
    При работе с ключами на алгоритме ГОСТ 2012 следует инициализировать генератор параметрами шифрования TK26Z (предоставляется провайдером).
    Алгоритм шифрования GOST28147.
  2. Зашифрование сессионного ключа.
    2.1. Создание шифратора для зашифрования ключа. Применяется алгоритм трансформации "urn:ietf:params:xml:ns:cpxmlsec:algorithms:transport-gost2001". Cоздается эфемерный ключ, который согласуется с открытым ключом получателя, и формируется ключ согласования (на котором будет зашифрован сессионный ключ);
    2.2. Создание блока KeyInfo с сертификатом;
    2.3. Шифрование сессионного ключа происходит с помощью указанного асимметричного ключа (ГОСТ Р 34.10). Cессионный ключ используется для шифрования данных и в свою очередь так же шифруется.
    CALG_DH_GR3410_12_256_EPHEM - идентификатор алгоритма обмена ключей по Диффи-Хеллману на базе закрытого ключа эфемерной пары. Открытый ключ получается по ГОСТ Р 34.10 2012 (256 бит).
    CALG_DH_GR3410_12_512_EPHEM - идентификатор алгоритма обмена ключей по Диффи-Хеллману на базе закрытого ключа эфемерной пары. Открытый ключ получается по ГОСТ Р 34.10 2012 (512 бит).
  3. В блоке soapenv:Header в подписанном запросе добавляется блок , который содержит публичный сертификат пользователя в формате x509v3 (кодировке base64).
  4. Зашифрование документа.
    4.1. Создание шифратора в режиме зашифрования. Применяется алгоритм
    "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gost28147". Возможные параметры шифратора GostJCE/CBC/ISO10126Padding;
    4.2. Добавление зашифрованного сессионного ключа, полученного ранее (добавление блока KeyInfo;
    4.3. Зашифрование документа на сессионном ключе.

@spiridonovav
Copy link
Author

Выкладываю зашифрованный запрос. Зашифрован тестовым сертификатом ФСС для ЭЛН 2021 года. Параллельно дублирую на файлообменнике: https://dropmefiles.com/jQxmK

Это файл, который вам прислали из ФСС? Или сформированный вами?
Хотелось бы посмотреть пример зашифрованного сообщения, которое вам прислали из ФСС.

@alexnur
Copy link

alexnur commented Feb 4, 2021

Это файл, который вам прислали из ФСС? Или сформированный вами?
Хотелось бы посмотреть пример зашифрованного сообщения, которое вам прислали из ФСС.

Это файл подписанного зашифрованного запроса страхователя к тестовому сервису ФСС. Пример прислали из ФСС. Запрос рабочий.

@spiridonovav
Copy link
Author

Подставил зашифрованный ключ и зашифрованные данные из примера ФСС в свой запрос. Сервис нормально вернул ответ, который я, естественно, не смог расшифровать. Значит структура сообщения у меня верная.
Обратил внимание, что зашифрованный мной ключ имеет размер в BASE64 228 символов, а в примере ФСС 232 символа.
Это о чем-то нам может сказать?

@spiridonovav
Copy link
Author

spiridonovav commented Feb 20, 2021

На мой вопрос:

Спасибо за ответ:

Ошибка с шифрованием происходит потому, что был
изменен порядок формирования зашифрованного >сообщения, изменения описаны в спецификации. Если >вы для >работы своего ПО используете библиотеку
шифрования GostCryptography, то она была
переписана, прежняя версия не может корректно >работать с сервисом 2.0.*

Я исхожу из фактов: 1. С сервисом 1.1 наша программа работала без ошибок 2. Изменения, в части подписания/шифрования в спецификации сервиса 2.0, сводятся к: а) добавление сертификата отправителя в подписанное сообщение перед шифрованием б) в зашифрованное сообщение вместо сертификата отправителя (сервис 1.1) прикладывается сертификат ФСС. Все остальные буквы спецификации сервиса 2.0, в части подписания/шифрования, не отличаются от спецификации 1.1 и, следовательно, уже реализованы в программе, которая работает с сервисом 1.1. С другой стороны, вы утверждаете, что GostCryptography в исходном виде не может работать с сервисом 2.0. Это наводит на мысль, что спецификация сервиса 2.0 не полная и не содержит какие-то существенные технические нюансы, которые необходимо реализовать для работы с сервисом 2.0. Огромная просьба от всего человечества: опубликуйте эти технические детали, которые не позволяют GostCryptography работать с сервисом 2.0. Или опубликуйте исходный код GostCryptography из АРМ ФСС или еще как-то, но дайте информацию, а уж мы разберемся как доработать наше ПО. Надеюсь на вашу помощь в этом вопросе, так как обратиться больше просто не к кому!

Был получен ответ:

Добрый день!
Заявка PPO2021-18913
Вопросы приведенные в заявке находятся вне компетенции технической поддержки. Техническая поддержка отвечает за работоспособность сервисов ЭЛН и поддерживаемых приложений, дает консультации по бизнес-процессам и применяемым форматно-логическим контролям, итп.
Техническая поддержка не дает консультаций и решений по разработке сторонних приложений.
Стандарты и алгоритмы, используемые при работе сервиса ЭЛН, являются открытыми и перечислены в спецификациях

Т.е. помощи от ФСС больше ждать бессмысленно.

@thpg
Copy link

thpg commented May 13, 2021

rashidus, вот успешно отправляемый:

(исправил, сперва был не тот)

запрос1.zip

@rashidus
Copy link

Спасибо!
Это на тестовый контур или прямо на рабочий?

@thpg
Copy link

thpg commented May 13, 2021

Это на тестовый, на рабочем нет такого больничного.

@rashidus
Copy link

Спасибо :) ошибка ушла! Подписание и расшифровка работают!

@OSnopkov
Copy link

Приложил три файла с этапами подписи и шифрования. Третий успешно отправляется.

успешные.zip

Добрый день!
Прошу помощи, беру ваш файл (xstep2.xml), заполняю его своими данными, причем оставляю номер ЛН и СНИЛС. Подписываю своим сертификатом, но при отправке в ФСС (тестовый контур) получаю ответ: ЭЦП неверна. INVALID_SIGNATURE ЭП недействительна.

@thpg
Copy link

thpg commented May 14, 2021

OSnopkov, так второй файл с подписью. Если поменять данные, то подпись станет некорректной.

@OSnopkov
Copy link

OSnopkov, так второй файл с подписью. Если поменять данные, то подпись станет некорректной.

Меняю регистрационный номер ФСС. Номер ЭЛН и СНИЛС оставляю.
Далее рассчитываю Hash (Body).
Затем подписываю данные (SignedInfo).
Собираю весь файл, подставив все полученные данные, вставляю свой сертификат (расчеты все велись используя его же).
Но в итоге получаю ошибку...

@wrx888
Copy link

wrx888 commented May 14, 2021

@alexnur, а у метода Sign есть параметр xPath, стандартно это
/soapenv:Envelope/soapenv:Body
, я же правильно понимаю, что если хочу чтобы врач подписал именно только период свой, то вместо стандартного нужно прописывать именно путь до этой ветки? Типа такого?
/soapenv:Envelope/soapenv:Body/prParseFilelnlpuRequest/pXmlFile/rowset/row/treatPeriods/treatFullPeriod/treatPeriod
или я не правильно понимаю как работает данный метод?

@alexnur
Copy link

alexnur commented May 14, 2021

@wrx888 у меня не было задачи отправки ЭЛН в ФСС да еще от мед.организации, соответственно подсказать тут не смогу, мне даже декомпилированная GostCryptography от ФСС тут не поможет, т.к. "АРМ расчета ФСС" только для страхователей, не МО.

@wrx888
Copy link

wrx888 commented May 17, 2021

А есть тут кто работает с этой библиотекой по пути @alexnur и отправляет данные в ФСС как МО?

@rashidus
Copy link

@wrx888 я делаю отправку, но как страхователь.
Выяснил, что при отправке данных библиотека GostCryptography используется только для шифрования-расшифровки, подписывается как-то по-другому. А вот при получении и для подписания, и для шифрования/расшифровки используется библиотека.
Подписание до сих пор не смог победить. Все время получаю ошибки

  • Отсутствует подпись головной организации
  • Отсутствует подпись Руководителя
  • Отсутствует подпись Гл.Бухгалтера
  • В сертификате организации отсутствует ОГРН (ОГРНИП), а также отсутствует уполномоченный представитель с таким сертификатом ЭП. Необходимо использовать сертификат с ОГРН (ОГРНИП) либо оформить доверенность для уполномоченного представителя

Никто не сталкивался с таким поведением? Сверил отправляемый запрос с представленным в спецификации - есть небольшие отличия, но подписи все на месте. В сертификатах ОГРН есть, совпадает с нашим.
Для подписания использую библиотеку из состава ARM FSS с парой написанных методов.

@wrx888
Copy link

wrx888 commented May 18, 2021

Есть там функция для подписи, выше писали
_interface01.signSOAPMessage
Если отсутствует подпись, то значит не туда ее вставляете, приложите файл, который отправляете (до шифрования конечно)

Как использовать.

  1. Качаем "АРМ подготовки расчетов для ФСС": https://lk.fss.ru/eln.html (прямая ссылка: http://fss.ru/ru/fund/download/55818/index.shtml)
  2. Устанавливаем это ПО. После установки идем по пути установленной программы (C:\FSSRF\ARM_FSS или C:\FSSRF.net\ARM_FSS_NET если сетевая версия). Копируем куда-нибудь библиотеку GostCryptography,dll.
  3. На текущий момент это fork от ФСС mit-версии GostCryptography 2.0.2.0 от 14.11.2019. Размер 205 824 байт.
  4. Добавляем ссылку (Reference) из своего проекта на GostCryptography.dll от ФСС.
  5. Используем следующую болванку для SOAP-сообщения:
    public readonly static string FssQueryTemplate2 = "<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " + "xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"> " + "<soapenv:Body xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"> " + "<getPrivateLNDataRequest xmlns = \"http://www.fss.ru/integration/types/eln/ins/v01\"> " + "<regNum>динамически указать рег.номер</regNum> " + "<lnCode>динамически указать номер ЭЛН</lnCode> " + "<snils>динамически указать СНИЛС</snils> " + "</getPrivateLNDataRequest> " + "</soapenv:Body>" + "</soapenv:Envelope>";
  6. Добавляем данные по ЭЛН:
    XmlDocument doc = new XmlDocument(); doc.LoadXml(GlobalVariables.FssQueryTemplate2); foreach (XmlElement xe in getPrivateLnDataNode) { if (xe.Name == "regNum") { xe.FirstChild.Value = regNumber; } else if (xe.Name == "lnCode") { xe.FirstChild.Value = dataForFss.LnCode; } else if (xe.Name == "snils") { xe.FirstChild.Value = dataForFss.PensNo; } } doc.PreserveWhitespace = true;
  7. Далее полученный XML используем в классе MyCprypt.

`public class MyCrypt
{
#region Конструктор. Подписание/шифрование для ФСС по спецификации 2.0.
///

/// Подписание/шифрование для ФСС по спецификации 2.0.
///

/// Имя криптопровайдера, например "Crypto-Pro CSP 256".
public MyCrypt(string cryptoProvider)
{
_cryptoProvider = cryptoProvider;
}
#endregion

    private IInterface01 _interface01 = new CryproServer01();
    private string _cryptoProvider;

    #region Подписание запроса для ФСС по спецификации 2.0.
    /// <summary>
    ///  Подписание запроса для ФСС по спецификации 2.0.
    /// </summary>
    /// <param name="request"> Подписываемое сообщение SOAP. </param>
    /// <param name="signingCertificate"> Серийный номер сертификата страхователя. </param>
    /// <param name="regnumber"> Регистрационный номер страхователя (цифры). </param>
    /// <param name="xPath"> Дополнительная информация. Указывать необязательно. </param>
    public string Sign(
              string request,
              string signingCertificate,
              string regnumber,
              string xPath = "/soapenv:Envelope/soapenv:Body")
    {
        string id = "REGNO_" + regnumber;
        string actor = "http://eln.fss.ru/actor/insurer/" + regnumber;
        string result = _interface01.signSOAPMessage(_cryptoProvider, request,
               signingCertificate, xPath, id, actor);

        return result;
    }
    #endregion

    #region Шифрование запроса для ФСС по спецификации 2.0.
    /// <summary>
    ///  Шифрование для ФСС по спецификации 2.0.
    /// </summary>
    /// <param name="senderCert"> Серийный номер сертификата страхователя. </param>
    /// <param name="recieverCert"> Серийный номер сертификата уполномоченного лица ФСС. </param>
    /// <param name="message"> Cообщение SOAP, которое необходимо зашифровать. </param>
    /// <param name="wrapInNewSoapMessage"> При TRUE (по умолчанию) сообщение после шифрования будет обёрнуто в новое 
    /// SOAP-сообщение. </param>
    public string Encrypt(string senderCert, string recieverCert, string message, bool wrapInNewSoapMessage=true )
    {
        // Серийные номера сертификатов могут содержать невидимые символы.
        // Подробности: https://support.microsoft.com/ru-ru/topic/certificate-thumbprint-displayed-in-mmc-certificate-snap-in-has-extra-invisible-unicode-character-c9e58dcb-f39a-d0a1-f7fc-bcaaa6fe64e4
        // Необходимо избавиться от них при их наличии.
        var rgx = new Regex("[^a-fA-F0-9]");
        senderCert = rgx.Replace(senderCert, string.Empty).ToUpper();
        recieverCert = rgx.Replace(recieverCert, string.Empty).ToUpper();
        string result = _interface01.encryptSOAPMessage(_cryptoProvider, senderCert, recieverCert, message);
        if (wrapInNewSoapMessage)
        {
            result = "<?xml version=\"1.0\"?>" + "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"><SOAP-ENV:Header/><SOAP-ENV:Body>" + result;
            result += "</SOAP-ENV:Body></SOAP-ENV:Envelope>";
        }

        return result;
    }
    #endregion

    #region Дешифрование овтета из ФСС по спецификации 2.0.
    /// <summary>
    ///  Дешифрование овтета из ФСС по спецификации 2.0.
    /// </summary>
    /// <param name="recieverCert"> Серийный номер сертификата страхователя. </param>
    /// <param name="message"> Зашифрованное сообщение SOAP, полученное из ФСС. </param>
    public string Decrypt(string recieverCert, string message)
    {
        string result = _interface01.decryptSOAPMessage(_cryptoProvider, recieverCert, message);

        return result;
    }
    #endregion

}`

@rashidus
Copy link

Вот запрос перед шифрованием. Убрал из запроса данные больничного (между тегами row) и заменил данные страхователя и номер больничного.

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
	<s:Header>
		<wsse:Security S:actor="http://eln.fss.ru/actor/insurer/0000000000/900000000001" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
			<ds:Signature>
				<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
					<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments" />
					<SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256" />
					<Reference URI="#REGNO_0000000000">
						<Transforms>
							<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
						</Transforms>
						<DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256" />
						<DigestValue>H7P+NobvUo2gKvvTxWOnhHnKmE+fMtfsv8hQ5Bft3yk=</DigestValue>
					</Reference>
				</SignedInfo>
				<SignatureValue xmlns="http://www.w3.org/2000/09/xmldsig#">IBFOmOKdW4mDV+ggLIVCGtUI0WP4ve43G2nWi4tfLJMdhpINdRx1SJygYb9otWj8OHidQj85WUBSamO6qV12Cg==</SignatureValue>
				<ds:KeyInfo>
					<wsse:SecurityTokenReference>
						<wsse:Reference URI="#http://eln.fss.ru/actor/insurer/0000000000/900000000001" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
					</wsse:SecurityTokenReference>
				</ds:KeyInfo>
			</ds:Signature>
			<wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="http://eln.fss.ru/actor/insurer/0000000000/900000000001">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</wsse:BinarySecurityToken>
		</wsse:Security>
		<wsse:Security S:actor="http://eln.fss.ru/actor/chief/0000000000/900000000001" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
			<ds:Signature>
				<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
					<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments" />
					<SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256" />
					<Reference URI="#REGNO_0000000000">
						<Transforms>
							<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
						</Transforms>
						<DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256" />
						<DigestValue>H7P+NobvUo2gKvvTxWOnhHnKmE+fMtfsv8hQ5Bft3yk=</DigestValue>
					</Reference>
				</SignedInfo>
				<SignatureValue xmlns="http://www.w3.org/2000/09/xmldsig#">ThJlabcQ7dQCTh4PEHNea34nlHzoBEUpORNL9weslkNvoCmXQRQU1slbnRv2IvKjj7hTYdtOYYoZ7gqCINcrJQ==</SignatureValue>
				<ds:KeyInfo>
					<wsse:SecurityTokenReference>
						<wsse:Reference URI="#http://eln.fss.ru/actor/chief/0000000000/900000000001" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
					</wsse:SecurityTokenReference>
				</ds:KeyInfo>
			</ds:Signature>
			<wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="http://eln.fss.ru/actor/chief/0000000000/900000000001">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</wsse:BinarySecurityToken>
		</wsse:Security>
		<wsse:Security S:actor="http://eln.fss.ru/actor/accountant/0000000000/900000000001" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
			<ds:Signature>
				<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
					<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments" />
					<SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256" />
					<Reference URI="#REGNO_0000000000">
						<Transforms>
							<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
						</Transforms>
						<DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256" />
						<DigestValue>H7P+NobvUo2gKvvTxWOnhHnKmE+fMtfsv8hQ5Bft3yk=</DigestValue>
					</Reference>
				</SignedInfo>
				<SignatureValue xmlns="http://www.w3.org/2000/09/xmldsig#">1MVuqc78AgKwjQuXn+q3T9jfFOuIICzVUGRo0XTpf46EofSm2mBt2Aujt8pr8+0Y+aNdoduB+V4SUeaVwVQrfg==</SignatureValue>
				<ds:KeyInfo>
					<wsse:SecurityTokenReference>
						<wsse:Reference URI="#http://eln.fss.ru/actor/accountant/0000000000/900000000001" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
					</wsse:SecurityTokenReference>
				</ds:KeyInfo>
			</ds:Signature>
			<wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="http://eln.fss.ru/actor/accountant/0000000000/900000000001">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</wsse:BinarySecurityToken>
		</wsse:Security>
	</s:Header>
	<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="REGNO_0000000000">
		<prParseReestrFileRequest xmlns="http://www.fss.ru/integration/types/eln/ins/v01">
			<request>
				<regNum>0000000000</regNum>
				<pXmlFile>
					<rowset d6p1:author="ФИО" d6p1:phone="8(код)те-ле-фон" d6p1:email="email" d6p1:version="2.0" d6p1:software="Microsoft Dynamics Axapta" d6p1:version_software="5.0" xmlns:d6p1="http://www.fss.ru/integration/types/eln/v01">
						<row>
						</row>
					</rowset>
				</pXmlFile>
			</request>
		</prParseReestrFileRequest>
	</s:Body>
</s:Envelope>

@wrx888
Copy link

wrx888 commented May 18, 2021

А три раза <wsse:Security это так и надо Вам?
И вставляете ли Вы в хидер данные о сертификате?
3. В блоке <soapenv:Header> в подписанном запросе добавляется блок <X509Certificate>, который содержит публичный сертификат пользователя в формате x509v3 (кодировке base64).

@rashidus
Copy link

Три подписи должно быть при отправке данных по больничному в ФСС.
Данные о сертификате вставляются на этапе шифрования. С ним вроде проблем нет, потому что приходит нормальный расшифрованный ответ именно про подписи. Если с шифрованием проблемы, то служба сообщает, что не удалось расшифровать запрос. Перепроверил зашифрованный запрос - там такие данные есть.
Кстати, и в версии 1.1 тоже было 3 подписи - страхователя (организации), руководителя и гл.бухгалтера), как в версии 2.0

@rashidus
Copy link

Подписать и отправить данные ЭЛН удалось. Метод GostCryptography из состава ARM FSS не работает. Но сработало самописное решение для версии 1.1.

@rashidus
Copy link

Получилось переписать шифрование/расшифровку на GostCryptography от AlexMAS (этот репозиторий) и избавиться от ужасно доработанной библиотеки из состава ARM FSS.
Вот код

#region ЭЛН 2.0 расшифровка
public static XmlDocument DecryptXmlDocument(XmlDocument encryptedXmlDocument, X509Certificate2 insurerCertificate)
{
    XmlNodeList encDataNodes = encryptedXmlDocument.DocumentElement.GetElementsByTagName("xenc:EncryptedData");
    encryptedXmlDocument = new XmlDocument();
    encryptedXmlDocument.LoadXml(encDataNodes.Item(0).OuterXml);

    if (insurerCertificate != null)
    {
        XmlNodeList certificatesNodes = encryptedXmlDocument.DocumentElement.GetElementsByTagName("ds:X509Certificate");
        XmlElement xml = new KeyInfoX509Data(insurerCertificate).GetXml();
        certificatesNodes.Item(0).FirstChild.Value = xml.FirstChild.FirstChild.Value;
    }

    GostCryptography.Xml.GostEncryptedXml gostEncryptedXml = new GostCryptography.Xml.GostEncryptedXml(encryptedXmlDocument);
    XmlElement documentElement = encryptedXmlDocument.DocumentElement;
    if (documentElement != null)
    {
        EncryptedData encryptedData = new EncryptedData();
        encryptedData.LoadXml(documentElement);
        SymmetricAlgorithm decryptionKey = GetDecryptionKey(encryptedData);
        if (decryptionKey != null)
        {
            byte[] decryptedData = gostEncryptedXml.DecryptData(encryptedData, decryptionKey);
            gostEncryptedXml.ReplaceData(documentElement, decryptedData);
        }
    }
    return encryptedXmlDocument;
}

private static SymmetricAlgorithm GetDecryptionKey(EncryptedData encryptedData)
{
    SymmetricAlgorithm symmetricAlgorithm = (SymmetricAlgorithm)null;
    foreach (object obj1 in encryptedData.KeyInfo)
    {
        if (obj1 is KeyInfoEncryptedKey)
        {
            EncryptedKey encryptedKey = ((KeyInfoEncryptedKey)obj1).EncryptedKey;
            if (encryptedKey != null)
            {
                foreach (object obj2 in encryptedKey.KeyInfo)
                {
                    if (obj2 is KeyInfoX509Data)
                    {
                        ArrayList certificates = ((KeyInfoX509Data)obj2).Certificates;
                        X509Certificate2 certificate = (X509Certificate2)null;
                        foreach (X509Certificate2 x509Certificate2 in certificates)
                        {
                            //certificate = GostCertificatesDispatcher.FindCertificate(x509Certificate2.SerialNumber); //TODO
                            certificate = SecurityUtils.GetCertificateFromStoreCore(StoreName.My, StoreLocation.CurrentUser, X509FindType.FindBySerialNumber, x509Certificate2.SerialNumber);
                            if (certificate != null)
                            {
                                break;
                            }

                        }
                        if (System.Security.Cryptography.X509Certificates.X509CertificateHelper.GetPrivateKeyAlgorithm(certificate) is GostCryptography.Base.GostAsymmetricAlgorithm privateKeyAlgorithm7)
                        {
                            symmetricAlgorithm = GostCryptography.Xml.GostEncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, privateKeyAlgorithm7);
                            break;
                        }
                    }
                }
            }
        }
    }
    return symmetricAlgorithm;
}
#endregion

#region ЭЛН 2.0 шифрование
public static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, X509Certificate2 fssCertificate, X509Certificate2 insurerCertificate)
{
    XmlDocument xmlAppendedSenderCert = AppendInsurerCertificate(xmlDocument, insurerCertificate);

    GostCryptography.Config.GostCryptoConfig.ProviderType = GostCryptography.Base.ProviderType.CryptoPro;
    GostCryptography.Config.GostCryptoConfig.ProviderType_2012_512 = GostCryptography.Base.ProviderType.CryptoPro_2012_512;
    GostCryptography.Config.GostCryptoConfig.ProviderType_2012_1024 = GostCryptography.Base.ProviderType.CryptoPro_2012_1024;
    GostCryptography.Xml.GostEncryptedXml gostEncryptedXml = new GostCryptography.Xml.GostEncryptedXml(GostCryptography.Base.ProviderType.CryptoPro);
    XmlElement documentElement = xmlAppendedSenderCert.DocumentElement;
    if (documentElement != null)
    {
        EncryptedData encryptedData = new EncryptedData();
        encryptedData.Type = "http://www.w3.org/2001/04/xmlenc#Element";
        encryptedData.KeyInfo = new KeyInfo();

        encryptedData.EncryptionMethod = new EncryptionMethod("urn:ietf:params:xml:ns:cpxmlsec:algorithms:gost28147");
        using (GostCryptography.Gost_28147_89.Gost_28147_89_SymmetricAlgorithm symmetricAlgorithm_orig = new GostCryptography.Gost_28147_89.Gost_28147_89_SymmetricAlgorithm(GostCryptography.Base.ProviderType.CryptoPro_2012_512))
        {
            byte[] numArray = gostEncryptedXml.EncryptData(documentElement, symmetricAlgorithm_orig, false);
            byte[] cipherValue = GostEncryptedXml.EncryptKey(symmetricAlgorithm_orig, (GostAsymmetricAlgorithm)fssCertificate.GetPublicKeyAlgorithm());
            EncryptedKey encryptedKey = new EncryptedKey();
            encryptedKey.CipherData = new CipherData(cipherValue);
            encryptedKey.EncryptionMethod = new EncryptionMethod("urn:ietf:params:xml:ns:cpxmlsec:algorithms:transport-gost2001");
            encryptedKey.KeyInfo.AddClause((KeyInfoClause)new KeyInfoX509Data(fssCertificate));
            encryptedData.KeyInfo.AddClause((KeyInfoClause)new KeyInfoEncryptedKey(encryptedKey));
            encryptedData.CipherData.CipherValue = numArray;
        }

        GostEncryptedXml.ReplaceElement(documentElement, encryptedData, false);
    }
    string result = "<?xml version=\"1.0\"?>" +
                    "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
                    "<soapenv:Header/>" +
                    "<soapenv:Body>" +
                    $"{xmlAppendedSenderCert.DocumentElement.OuterXml}" +
                    "</soapenv:Body>" +
                    "</soapenv:Envelope>";
    XmlDocument newXmlDocument = new XmlDocument();
    newXmlDocument.LoadXml(result);

    return newXmlDocument;
}

private static XmlNamespaceManager GetNameTable(XmlDocument x)
{
    XmlNamespaceManager namespaceManager = new XmlNamespaceManager(x.NameTable);
    namespaceManager.AddNamespace("soap-env", Xmlns.soapenv);
    namespaceManager.AddNamespace("xenc", Xmlns.xmlenc);
    namespaceManager.AddNamespace("s", Xmlns.soapenv);
    namespaceManager.AddNamespace("soap", Xmlns.soapenv);
    namespaceManager.AddNamespace("soapenv", Xmlns.soapenv);
    namespaceManager.AddNamespace("wsse", Xmlns.wsse);
    namespaceManager.AddNamespace("ns1", Xmlns.eln);
    namespaceManager.AddNamespace("eln", Xmlns.eln);
    namespaceManager.AddNamespace("ds", Xmlns.ds);
    return namespaceManager;
}

private static XmlDocument AppendInsurerCertificate(XmlDocument xmlDocument, X509Certificate2 insurerCertificate)
{
    XmlNamespaceManager nameTable = GetNameTable(xmlDocument);
    XmlNode node = xmlDocument.CreateNode("element", "ds:X509Certificate", "http://www.w3.org/2000/09/xmldsig#");
    node.InnerText = Convert.ToBase64String(insurerCertificate.RawData);
    XmlNode xmlNode = xmlDocument.SelectSingleNode("/soapenv:Envelope/soapenv:Header", nameTable);
    xmlNode.AppendChild(node);
    return xmlDocument;
}
#endregion

@RashitFatkullin
Copy link

Добрый день @rashidus.
Можете пожалуйста разместить код подписания сообщения? У меня не выходит подписать. Похоже ошибочно формируется хэш (DigestValue)
Визуально все как в документации:

<soapenv:Envelope xmlns:soapenv=http://schemas.xmlsoap.org/soap/envelope/ xmlns:ds=http://www.w3.org/2000/09/xmldsig# xmlns:wsse=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd xmlns:wsu=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd>
  <soapenv:Header>
    <wsse:Security soapenv:actor=http://eln.fss.ru/actor/insurer/xxxxxxxxxx/yyyyyyyyyy>
      <wsse:BinarySecurityToken EncodingType=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary ValueType=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3 wsu:Id=http://eln.fss.ru/actor/insurer/xxxxxxxxxx/yyyyyyyyyy>MIIKKjCCCdegAwIBAgIRArhHdQC8rLGwS4dSLWF93+EwCgYIKoUDBwEBAwIwggGJMR4wHAYJKoZI......</wsse:BinarySecurityToken>
      <Signature xmlns=http://www.w3.org/2000/09/xmldsig#>
        <SignedInfo>
          <CanonicalizationMethod Algorithm=http://www.w3.org/2001/10/xml-exc-c14n#WithComments />
          <SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256" />
          <Reference URI="#ELN_yyyyyyyyyy">
            <Transforms>
              <Transform Algorithm=http://www.w3.org/2001/10/xml-exc-c14n# />
            </Transforms>
            <DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256" />
            <DigestValue>+sevX6YOMBoQ5Tra5SAN16dtiAXMJqJc3BXuK3oucu0=</DigestValue>
          </Reference>
        </SignedInfo>
        <SignatureValue>Dzdlhzd7osnrIuExiSOAJD70e/LWBTguMh0I3349hfSqYGFeEukz0pPIjNZu+5m+RjDB4c38PSp2VRo+C5+2mQ==</SignatureValue>
        <KeyInfo>
          <wsse:SecurityTokenReference>
            <wsse:Reference URI="#http://eln.fss.ru/actor/insurer/xxxxxxxxxx/yyyyyyyyyy" />
          </wsse:SecurityTokenReference>
        </KeyInfo>
      </Signature>
    </wsse:Security>
    <wsse:Security soapenv:actor=http://eln.fss.ru/actor/chief/xxxxxxxxxx/yyyyyyyyyy>
      <wsse:BinarySecurityToken EncodingType=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary ValueType=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3 wsu:Id=http://eln.fss.ru/actor/chief/xxxxxxxxxx/yyyyyyyyyy>MIIL1DCCC4GgAwIBAgIRARK1ygAwrBqMTPdiOqGliWUwCgYIKoUDBwEBAwIwggGJMSIwIAYJKoZI.....</wsse:BinarySecurityToken>
      <Signature xmlns=http://www.w3.org/2000/09/xmldsig#>
        <SignedInfo>
          <CanonicalizationMethod Algorithm=http://www.w3.org/2001/10/xml-exc-c14n#WithComments />
          <SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256" />
          <Reference URI="#ELN_yyyyyyyyyy">
            <Transforms>
              <Transform Algorithm=http://www.w3.org/2001/10/xml-exc-c14n# />
            </Transforms>
            <DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256" />
            <DigestValue>+sevX6YOMBoQ5Tra5SAN16dtiAXMJqJc3BXuK3oucu0=</DigestValue>
          </Reference>
        </SignedInfo>
        <SignatureValue>AGAmFv0m6X7PklJgdx066b9URHYbeNKsgvB5yEWuKm8vM6x456Ow08WWrBPfQvH/aVSivp+Lwzpi0Yf14X+Uew==</SignatureValue>
        <KeyInfo>
          <wsse:SecurityTokenReference>
            <wsse:Reference URI="#http://eln.fss.ru/actor/chief/xxxxxxxxxx/yyyyyyyyyy" />
          </wsse:SecurityTokenReference>
        </KeyInfo>
      </Signature>
    </wsse:Security>
    <wsse:Security soapenv:actor=http://eln.fss.ru/actor/accountant/xxxxxxxxxx/yyyyyyyyyy>
      <wsse:BinarySecurityToken EncodingType=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary ValueType=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3 wsu:Id=http://eln.fss.ru/actor/accountant/xxxxxxxxxx/yyyyyyyyyy>MIINvzCCDWygAwIBAgIRAfNdsQBBrLmATA5OsptSI24wCgYIKoUDBwEBAwIwggGJMSIwIAYJKoZI....</wsse:BinarySecurityToken>
      <Signature xmlns=http://www.w3.org/2000/09/xmldsig#>
        <SignedInfo>
          <CanonicalizationMethod Algorithm=http://www.w3.org/2001/10/xml-exc-c14n#WithComments />
          <SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256" />
          <Reference URI="#ELN_yyyyyyyyyy">
            <Transforms>
              <Transform Algorithm=http://www.w3.org/2001/10/xml-exc-c14n# />
            </Transforms>
            <DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256" />
            <DigestValue>+sevX6YOMBoQ5Tra5SAN16dtiAXMJqJc3BXuK3oucu0=</DigestValue>
          </Reference>
        </SignedInfo>
        <SignatureValue>rRsNhbQ6/HgIziRC22+6hX2L5Msu4tgQ9noz8Phgvt1gpOfXHzxE2DF8cppoc5ICcdQNYJUB8qo+oabHolVAZw==</SignatureValue>
        <KeyInfo>
          <wsse:SecurityTokenReference>
            <wsse:Reference URI="#http://eln.fss.ru/actor/accountant/xxxxxxxxxx/yyyyyyyyyy" />
          </wsse:SecurityTokenReference>
        </KeyInfo>
      </Signature>
    </wsse:Security>
  </soapenv:Header>
  <soapenv:Body>
    <v01:prParseReestrFileRequest xmlns:v01=http://www.fss.ru/integration/types/eln/ins/v01 xmlns:v011=http://www.fss.ru/integration/types/eln/v01 xmlns:wsu=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance>
      <v01:request>
        <v01:regNum>xxxxxxxxxx</v01:regNum>
        <v01:pXmlFile>
          <v01:rowset v011:author="" v011:email="" v011:phone="" v011:software="Microsoft Dynamics AX" v011:version="2.0" v011:version_software="2012 R2">
            <v01:row wsu:Id="ELN_yyyyyyyyyy">
              .....
            </v01:row>
          </v01:rowset>
        </v01:pXmlFile>
      </v01:request>
    </v01:prParseReestrFileRequest>
  </soapenv:Body>
</soapenv:Envelope>

ответ от сервиса ФСС:

<soap:Body wsu:Id="OGRN_xxxxxxxxxxxxxxxxxxxxxx">
		<prParseReestrFileResponse xmlns="http://www.fss.ru/integration/types/eln/ins/v01" xmlns:ns2="http://www.fss.ru/integration/types/eln/v01" xmlns:ns3="http://www.fss.ru/integration/types/eln/mse/v01" xmlns:ns4="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ns5="http://www.fss.ru/integration/types/fault/v01" xmlns:ns6="http://www.fss.ru/integration/types/common/v01">
			<wsResult>
				<ns2:requestId>LNDATAINS_xxxxxxxxxxxx_xxxx_xx_xx_xxxxx</ns2:requestId>
				<ns2:status>0</ns2:status>
				<ns2:mess>Найдены ошибки при выполнении форматно-логических проверок</ns2:mess>
				<ns2:info>
					<ns2:infoRowset>
						<ns2:infoRow>
							<ns2:rowNo>1</ns2:rowNo>
							<ns2:lnCode>xxxxxxxxxxxxxx</ns2:lnCode>
							<ns2:status>0</ns2:status>
							<ns2:errors>
								<ns2:error>
									<ns2:errCode>ERR_SIGN</ns2:errCode>
									<ns2:errMess>Некорректная подпись головной организации: ЭЦП неверна. INVALID_SIGNATURE ЭП недействительна. Обратитесь к разработчику программного обеспечения, на котором осуществлялось подписание данных.</ns2:errMess>
								</ns2:error>
								<ns2:error>
									<ns2:errCode>ERR_SIGN</ns2:errCode>
									<ns2:errMess>Некорректная подпись руководителя: ЭЦП неверна. INVALID_SIGNATURE ЭП недействительна. Обратитесь к разработчику программного обеспечения, на котором осуществлялось подписание данных.</ns2:errMess>
								</ns2:error>
								<ns2:error>
									<ns2:errCode>ERR_SIGN</ns2:errCode>
									<ns2:errMess>Некорректная подпись Гл.Бухгалтера: ЭЦП неверна. INVALID_SIGNATURE ЭП недействительна. Обратитесь к разработчику программного обеспечения, на котором осуществлялось подписание данных.</ns2:errMess>
								</ns2:error>
							</ns2:errors>
						</ns2:infoRow>
					</ns2:infoRowset>
				</ns2:info>
			</wsResult>
		</prParseReestrFileResponse>
	</soap:Body>

Заранее спасибо.

@rashidus
Copy link

Подписание (не менялось с версии 1.1)

#region подписание при отправке
public override XmlDocument PrepareMessage()
{
    InitRegNum();
    PrepareNamespaces(Message);

    XmlNodeList rowNode = Message.GetElementsByTagName("row", Xmlns.fssWsdl);

    foreach (XmlElement row in rowNode)
    {
        XmlNodeList lnCode = row.GetElementsByTagName("lnCode", Xmlns.fssWsdl);

        if (lnCode != null && lnCode.Count == 1)
        {
            XmlElement lnCodeTag = lnCode[0] as XmlElement;
            string lnNum = lnCodeTag.InnerText;

            if (!String.IsNullOrEmpty(lnNum))
            {
                row.RemoveAllAttributes();

                row.SetAttribute("xmlns:wsu", Xmlns.wsu);
                row.SetAttribute("Id", Xmlns.wsu, $"ELN_{lnNum}");

                AddSecurityToken(Message, InsurerCertificate, $"insurer/{RegNum}/{lnNum}", $"ELN_{lnNum}");
                AddSecurityToken(Message, ChiefCertificate, $"chief/{RegNum}/{lnNum}", $"ELN_{lnNum}");
                AddSecurityToken(Message, AccountantCertificate, $"accountant/{RegNum}/{lnNum}", $"ELN_{lnNum}");
            }
        }
    }
    return Message;
}
#endregion
#region подписание при получении
public override XmlDocument PrepareMessage()
{
    InitRegNum();
    PrepareNamespaces(Message);
    PrepareBody(Message, $"REGNO_{RegNum}");
    AddSecurityToken(Message, InsurerCertificate, $"insurer/{RegNum}", $"REGNO_{RegNum}");
    return Message;
}
protected void PrepareBody(XmlDocument document, string referenceUri)
{
    XmlNodeList bodyNode = document.GetElementsByTagName("Body", Xmlns.soapenv);

    if (bodyNode != null && bodyNode.Count == 1)
    {
        XmlElement body = bodyNode[0] as XmlElement;
        body.SetAttribute("xmlns:wsu", Xmlns.wsu);
        body.SetAttribute("Id", Xmlns.wsu, referenceUri);
    }
}
#endregion
protected virtual void InitRegNum()
{
    XmlNodeList nodeList = Message.GetElementsByTagName("regNum", Xmlns.fssWsdl);

    if (nodeList != null && nodeList.Count == 1)
    {
        XmlElement regNumElement = nodeList[0] as XmlElement;

        if (String.IsNullOrEmpty(RegNum))
        {
            RegNum = regNumElement.InnerText;
        }
    }
}
protected virtual void PrepareNamespaces(XmlDocument document)
{
    XmlNamespaceManager ns = new XmlNamespaceManager(document.NameTable);

    ns.AddNamespace("soapenv", Xmlns.soapenv);
    ns.AddNamespace("ds", Xmlns.ds);
    ns.AddNamespace("wsse", Xmlns.wsse);
    ns.AddNamespace("wsu", Xmlns.wsu);
    ns.AddNamespace("xsd", Xmlns.xsd);
    ns.AddNamespace("xsi", Xmlns.xsi);
    ns.AddNamespace("xenc", Xmlns.xmlenc);
    ns.AddNamespace("sch", Xmlns.sch);
}
public virtual void AddSecurityToken(XmlDocument document, X509Certificate2 certificate, string wsseReferencePostfix, string referenceUri)
{
    XmlElement xmlDigitalSignature = GenerateSecurityToken(document, certificate, wsseReferencePostfix, referenceUri);

    XmlNodeList nodeList = document.GetElementsByTagName("Header", Xmlns.soapenv);

    if (nodeList != null && nodeList.Count == 1)
    {
        XmlElement security = document.CreateElement("wsse", "Security", Xmlns.wsse);
        security.SetAttribute("actor", Xmlns.soapenv, $"{Xmlns.wsseReferenceURI}{wsseReferencePostfix}");
        security.SetAttribute("xmlns:wsu", Xmlns.wsu);
        security.SetAttribute("xmlns:ds", Xmlns.ds);
        nodeList[0].AppendChild(security);

        XmlElement binarySecurityToken = document.CreateElement("wsse", "BinarySecurityToken", Xmlns.wsse);
        binarySecurityToken.SetAttribute("EncodingType", Xmlns.encodingType);
        binarySecurityToken.SetAttribute("ValueType", Xmlns.valueType);
        binarySecurityToken.SetAttribute("Id", Xmlns.wsu, $"{Xmlns.wsseReferenceURI}{wsseReferencePostfix}");
        binarySecurityToken.InnerText = Convert.ToBase64String(certificate.Export(X509ContentType.Cert));
        security.AppendChild(binarySecurityToken);

        security.AppendChild(xmlDigitalSignature);
    }
}
private static string GetSignatureMethod(X509Certificate2 certificate)
{
    // Имя алгоритма вычисляем динамически, чтобы сделать код теста универсальным

    using (var publicKey = (GostCryptography.Base.GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm()) //TODO
    {
        return publicKey.SignatureAlgorithm;
    }
}

private XmlElement GenerateSecurityToken(XmlDocument document, X509Certificate2 certificate, string wsseReferencePostfix, string referenceUri)
{
    XmlElement keyReference = document.CreateElement("wsse", "Reference", Xmlns.wsse);
    keyReference.SetAttribute("URI", $"#{Xmlns.wsseReferenceURI}{wsseReferencePostfix}");

    XmlElement keySecurityTokenReference = document.CreateElement("wsse", "SecurityTokenReference", Xmlns.wsse);
    keySecurityTokenReference.AppendChild(keyReference);

    KeyInfoNode keyInfoData = new KeyInfoNode(keySecurityTokenReference);

    KeyInfo keyInfo = new KeyInfo();
    keyInfo.AddClause(keyInfoData);

    Reference reference = new Reference
    {
        Uri = $"#{referenceUri}",
        DigestMethod = Xmlns.digestMethod
    };

    reference.AddTransform(new XmlDsigExcC14NTransform());

    FSSSignedXml signedXml = new FSSSignedXml(document)
    //GostSignedXml signedXml = new GostSignedXml(document)
    {
        SigningKey = certificate.GetPrivateKeyAlgorithm(), //TODO
        KeyInfo = keyInfo,
    };
    signedXml.AddReference(reference);
    signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
#pragma warning disable CS0612
    signedXml.SignedInfo.SignatureMethod = GetSignatureMethod(certificate);
#pragma warning restore CS0612
    signedXml.ComputeSignature();

    return signedXml.GetXml();
}

@rashidus
Copy link

Как только закончу рефакторинг проекта, постараюсь выложить. У нас WCF-служба, запущенная в Windows-службе, которая прозрачно подписывает и шифрует запросы и расшифровывает ответы.

@RashitFatkullin
Copy link

RashitFatkullin commented May 26, 2021

Добрый день.
Никак не выходит подписать отправку данных в ФСС (prParseReestrFile).
Ни своими старыми алгоритмами, ни тем что выложил @rashidus.
Хеш значение в узле DigestValue формируется одинаковое обоими алгоритмами.
Более того подписание запроса getPrivateLNData теми же способами проходит корректно, то есть для этого метода ЭЦП формируется без нареканий. Проверял оба файла (до шифрования) в службе проверки подписи https://www.justsign.me/verifyqca/Verify/ - тот же результат - все подписи для prParseReestrFile невалидны, подпись getPrivateLNData валидна, хотя и там и там использовались те же функции подписания и те же сертификаты.

Единственное отличие - подписанный узел - для getPrivateLNData это Body для prParseReestrFile это row.

Определяю узлы для подписания поиском в теле документа по Id:

internal class FSSSignedXml : SignedXml
    {
        public FSSSignedXml(XmlDocument document)
            : base(document)
        {
        }

        public override XmlElement GetIdElement(XmlDocument document, string idValue)
        {
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(document.NameTable);
            nsmgr.AddNamespace("wsu", Const.xmlns_wsu);
            var res = document.SelectSingleNode(String.Format("//*[@wsu:Id='{0}']", idValue), nsmgr) as XmlElement;

            return res;
        }
    }

Кто-нибудь сталкивался с подобной проблемой?
Может знает как проверить хэш для одного узла документа?
Влияет ли где в документе (в каком узле) определены пространства имен, например http://www.fss.ru/integration/types/eln/ins/v01 и http://www.fss.ru/integration/types/eln/v01

В чем могут быть вероятные причины проблемы?

Да, еще пробовал выкинуть из тела row метода prParseReestrFile все узлы кроме lnCode и подписать - проверил валидатором, все равно подпись некорректная.

@RashitFatkullin
Copy link

Добрый день.
Разобрался.

Сервис наконец-то вернул:

</soap:Header>
	<soap:Body wsu:Id="OGRN_xxxxxxxxxxx">
		<prParseReestrFileResponse xmlns="http://www.fss.ru/integration/types/eln/ins/v01" xmlns:ns2="http://www.fss.ru/integration/types/eln/v01" xmlns:ns3="http://www.fss.ru/integration/types/eln/mse/v01" xmlns:ns4="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ns5="http://www.fss.ru/integration/types/fault/v01" xmlns:ns6="http://www.fss.ru/integration/types/common/v01">
			<wsResult>
				<ns2:requestId>LNDATAINS_dddddddd_dddd_dd_ee_333333</ns2:requestId>
				<ns2:status>1</ns2:status>
				<ns2:mess>OK</ns2:mess>
				<ns2:info>
					<ns2:infoRowset>
						<ns2:infoRow>
							<ns2:rowNo>1</ns2:rowNo>
							<ns2:lnCode>xxxxxxxxxxxx</ns2:lnCode>
							<ns2:lnHash>B9866BA94C34734123B745C1C4F301D8</ns2:lnHash>
							<ns2:lnState>060</ns2:lnState>
							<ns2:status>1</ns2:status>
						</ns2:infoRow>
					</ns2:infoRowset>
				</ns2:info>
			</wsResult>
		</prParseReestrFileResponse>
	</soap:Body>

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

Переделал порядок следования на тот, который указан в образце http://www.api-fss.ru/files/V2_test_900000468164_p2.xml
и сервис принял мою xml.

Отдельное спасибо за помощь @rashidus

@rashidus
Copy link

https://github.com/rashidus/fss_integration

@alexnur
Copy link

alexnur commented Jul 18, 2021

Вопрос не совсем в тему, но тут, пожалуй наибольшее количество людей касаемо работы с ФСС, чем на другом ресурсе :)
У меня сервис по получению ЭЛН организован в виде веб-приложения ASP.Net (для спецификации ФСС 1.1) и ASP.Net Core 5 (для спецификации ФСС 2.0).
Сервис 1.1 работал на Windows Server, 2.0 - на линуксе.
Т.к. подписывать и расшифровывать должны клиентские АРМы (защитники информации запретили пробрасывать USB или ключи на сервер), то у них запускается с сервера подписанное консольное приложение click once (.Net Framework 4.5, с библиотекой GostCryptography.dll от ФСС) в фоновом режиме. В консольном приложении реализовано подписание, шифрование и дешифрование. Связь между веб-приложением и консольным приложением реализована в виде защищенных TCP-сокетов (SslStream), т.е. тоже зашифрована. Клиенты с ОС Windows.
Хочется избавить клиентов от необходимости установки .Net Framework и разворачивании консольного приложения.
Т.е. необходим некий плагин для браузера, который смог бы установить доверие и связь между клиентским криптопровайдером и javascript-кодом из браузера. Чтобы используя javascript из браузера, обращаться к криптопровайдеру. Ну и соответственно код на javascript должен уметь делать то самое - подписывать, шифровать и расшифровывать запросы в ФСС. Клиенты в будущем также перейдут на Linux.
Куда смотреть?

@CrazyB0y
Copy link

Куда смотреть?

Плагин криптопро для браузера

@Qulac596
Copy link

Добрый день, коллеги. Кто ни будь может объяснить, что означают эти сведения в спецификации:
"2. Для ЭП врача:
«http://eln.fss.ru/actor/doc/[№ ЭЛН]_[№ подписываемого блока*]doc
3. Для ЭП председателя ВК:
«http://eln.fss.ru/actor/doc/[№ ЭЛН]
[№ подписываемого блока*]_vk"

Где брать номер блока для подписи? Спасибо.

@DPonomarchuk
Copy link

Добрый день, коллеги. Кто ни будь может объяснить, что означают эти сведения в спецификации: "2. Для ЭП врача: «[http://eln.fss.ru/actor/doc/ ЭЛН]_[№ подписываемого блока*]doc 3. Для ЭП председателя ВК: «[http://eln.fss.ru/actor/doc/ ЭЛН][№ подписываемого блока*]_vk"

Где брать номер блока для подписи? Спасибо.

1 - Нарушение режима
2 - Результат закрытия
3 - Первый период
4 - Второй период
5 - Третий период

Примеры:
"http://eln.fss.ru/actor/doc/900000568880_3_doc" - подпись первого периода врачом
"http://eln.fss.ru/actor/doc/900000568880_5_vk" - подпись третьего периода пред вк*
"http://eln.fss.ru/actor/doc/900000568880_1_doc" - подпись нарушения режима врачом
"http://eln.fss.ru/actor/doc/900000568880_2_doc" - подпись результата закрытия врачом

  • подпись вк может быть только на периодах (3-5)

@Qulac596
Copy link

Спасибо огромное!

@zlovrednaya
Copy link

а чем закончилось с ошибкой #39 (comment)
Error in execution of data encrypting/decrypting operation. class org.apache.xml.security.encryption.XMLEncryptionException
?

@amedsoft
Copy link

При попытке зашифровать данные xml через GostCryptography.dll, возникает ошибка: ASN.1 encoded byte array contains invalid structure 'GostCrypography.Asn1.PKI.GostR34102001.GostR34102001 PublicKeyParameters
Шифровать пытаюсь данные XML сформированные в программе АРМ ФСС

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests