Форум программистов, компьютерный форум, киберфорум
C#: Веб-сервисы и WCF
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.58/89: Рейтинг темы: голосов - 89, средняя оценка - 4.58
0 / 0 / 0
Регистрация: 08.12.2015
Сообщений: 26
1

SOAP сервис ФСС. Подписывание запросов сертификатом

09.10.2017, 15:10. Просмотров 16490. Ответов 40
Метки нет (Все метки)

Доброго дня всем.
Есть задача наладить интеграцию с сервисом ФСС по Электронным больничным листам.
Сам сервис находится тут https://docs-test.fss.ru/eln.html
WSDL тут https://docs-test.fss.ru/FSSWS... nPort?WSDL
По спецификации используется стандарт безопасности OASIS Web Service Security.
Не могу разобраться как подписывать запросы сертификатом.
Если добавить стандартную ссылку на Веб-службу и работать ней, то не принимает сертификат. Или я его не туда указываю.
C#
1
2
3
            FileOperationsLnImplService service = new FileOperationsLnImplService();
            service.ClientCertificates.Add(x509Certificate2);
            FileOperationsLnUser_getNewLNNum_Out outDoc = service.getNewLNNum("ОГРН ОГРАНИЗАЦИИ");
Либо же формировать запрос вручную и подписывать самому? Если да, то как это можно сделать?

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

Заранее благодарен.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.10.2017, 15:10
Ответы с готовыми решениями:

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

SOAP сервис на PHP
Добрый день, Есть SOUP сервис написанный на PHP, не могу понять, что нужно поправить в wsdl, что...

SOAP запрос на ws сервис
Есть типовой документооборот, запущен веб сервис /doc_corp/ws/DmService /doc_corp/ws/Files и...

Сервис с методами SOAP и REST
Написать веб-сервис, который принимает строку и возвращает кол-во слов и символов. 2 метода в...

40
0 / 0 / 0
Регистрация: 10.03.2012
Сообщений: 22
30.10.2018, 16:06 21
Заготовка
C
1
TemplateSoapMessageForGetSickList =    "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHNvYXBlbnY6RW52ZWxvcGUgeG1sbnM6c29hcGVudj0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvc29hcC9lbnZlbG9wZS8iPgogIDxzb2FwZW52OkhlYWRlcj4KICA8L3NvYXBlbnY6SGVhZGVyPgogIDxzb2FwZW52OkJvZHkgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeG1sbnM6eHNkPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSI+CiAgICA8Z2V0UHJpdmF0ZUxORGF0YSB4bWxucz0iaHR0cDovL3J1L2licy9mc3MvbG4vd3MvRmlsZU9wZXJhdGlvbnNMbi53c2RsIj4KICAgICAgPHJlZ051bT41MzIwMDAwNDk5PC9yZWdOdW0+CiAgICAgIDxsbkNvZGU+OTEwMDAwMjczNjA5PC9sbkNvZGU+CiAgICAgIDxzbmlscz4xNDc1NDczNzk5OTwvc25pbHM+CiAgICA8L2dldFByaXZhdGVMTkRhdGE+CiAgPC9zb2FwZW52OkJvZHk+Cjwvc29hcGVudjpFbnZlbG9wZT4=";
X++
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
public   System.Xml.XmlElement GenerateSecurity(System.Xml.XmlDocument document, System.Security.Cryptography.X509Certificates.X509Certificate2 Certificate, string Prefix, string Id, string Iteration = "")
{
    System.Xml.XmlNodeList nodeList = null;
    System.Xml.XmlElement elemSecurity = null;
    System.Xml.XmlElement keySecurityTokenReference;
 
    System.Xml.XmlElement keyReference;
    System.Xml.XmlElement xmlDigitalSignature;
    System.Xml.XmlElement elemBinarySecurityToken,tmpXml;
    System.Xml.XmlNode nodeSecurity,tmpNode;
 
    int tmpCount;
    str tmp;
    System.Security.Cryptography.Xml.Reference  reference;
    System.Security.Cryptography.Xml.SignedXml  signer;
    System.Security.Cryptography.Xml.KeyInfo    keyInfo = new System.Security.Cryptography.Xml.KeyInfo();
    System.Security.Cryptography.Xml.KeyInfoNode keyInfoData;
    System.Security.Cryptography.Xml.SignedInfo signinfo = new System.Security.Cryptography.Xml.SignedInfo();
    System.Security.Cryptography.Xml.Signature  signature = new System.Security.Cryptography.Xml.Signature();
    System.Security.Cryptography.Xml.DataObject dataObject = new System.Security.Cryptography.Xml.DataObject();
    tmp = document.get_InnerXml();
    info(tmp);
    signer = new System.Security.Cryptography.Xml.SignedXml(document);
    signer.set_SigningKey(Certificate.get_PrivateKey());
    signature = signer.get_Signature();
 
    //<KeyInfo>
    keySecurityTokenReference = document.CreateElement("wsse", "SecurityTokenReference", #xmlns_wsse);
    keyReference = document.CreateElement("wsse", "Reference", #xmlns_wsse);
    keyReference.SetAttribute("URI", strfmt("#http://eln.fss.ru/actor/insurer/%1",Id));
    keySecurityTokenReference.AppendChild(keyReference);
    keyInfoData = new System.Security.Cryptography.Xml.KeyInfoNode(keySecurityTokenReference);
    keyInfo.AddClause(keyInfoData);
    signature.set_KeyInfo(keyInfo);
    //</KeyInfo>
 
    //<SignedInfo>
    // Создаем ссылку на подписываемый узел XML. В данном примере и в методических рекомендациях СМЭВ подписываемый узел soapenv:Body помечен идентификатором "body".
    //reference = new System.Security.Cryptography.Xml.Reference(strfmt("#{Prefix}_{Id}{(String.IsNullOrEmpty(Iteration) ? "" : $"_{Iteration}")}");
    reference = new System.Security.Cryptography.Xml.Reference(strfmt("%1_%2",Prefix, Id));
    // Задаём алгоритм хэширования подписываемого узла - ГОСТ Р 34.11-94. Необходимо использовать устаревший идентификатор данного алгоритма, т.к. именно такой идентификатор используется в СМЭВ.
    reference.set_DigestMethod("http://www.w3.org/2001/04/xmldsig-more#gostr3411");
    // Добавляем преобразование для приведения подписываемого узла к каноническому виду  по алгоритму http://www.w3.org/2001/10/xml-exc-c14n# в соответствии с методическими рекомендациями СМЭВ.
    reference.AddTransform(new System.Security.Cryptography.Xml.XmlDsigExcC14NTransform());
    // Добавляем ссылку на подписываемый узел.
    //signinfo = signer.get_SignedInfo();
    signinfo.AddReference(reference);
    signinfo.set_CanonicalizationMethod("http://www.w3.org/2001/10/xml-exc-c14n#");
    signinfo.set_SignatureMethod("http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411");
    //</SignedInfo>
    signature.set_SignedInfo(signinfo);
 
    // Вычисляем подпись.
    signer.ComputeSignature();
 
    // Получаем представление подписи в виде XML.
    xmlDigitalSignature = signer.GetXml();
 
    // Находим Header
    nodeList = document.GetElementsByTagName("Header", #xmlns_soapenv);
    tmpNode = nodeList.get_ItemOf(0);
    tmpCount = nodeList.get_Count();
    if (nodeList && tmpCount == 1)
    {
        // Добавление тега Security
        elemSecurity = document.CreateElement("wsse", "Security", #xmlns_wsse);
        elemSecurity.SetAttribute("actor", #xmlns_soapenv, strfmt("http://eln.fss.ru/actor/insurer/%1",Id));
        //elemSecurity.SetAttribute("xmlns:xsd", xmlns_xsd);
        elemSecurity.SetAttribute("xmlns:wsu", #xmlns_wsu);
        elemSecurity.SetAttribute("xmlns:ds", #xmlns_ds);
        tmpNode.AppendChild(elemSecurity);
    }
    nodeSecurity = elemSecurity;
    // Находим Security
    nodeSecurity.AppendChild(xmlDigitalSignature);
    elemBinarySecurityToken = document.CreateElement("wsse", "BinarySecurityToken", #xmlns_wsse);
    elemBinarySecurityToken.SetAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
    elemBinarySecurityToken.SetAttribute("ValueType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3");
    elemBinarySecurityToken.SetAttribute("Id", #xmlns_wsu, strfmt("http://eln.fss.ru/actor/insurer/%1",Id));
 
    elemBinarySecurityToken.set_InnerText(System.Convert::ToBase64String(Certificate.Export(System.Security.Cryptography.X509Certificates.X509ContentType::Cert)));
    nodeSecurity.AppendChild(elemBinarySecurityToken);
 
    return elemSecurity;
}

Вылетает на моменте signer.ComputeSignature(); Такое чувство, что не принимает шаблон или неправильно указываем саму подпись, методы типа signer.set_Signature() и signer.set_SigndeInfo в классе SignedXml отсутствуют...
0
11 / 11 / 1
Регистрация: 16.11.2011
Сообщений: 50
30.10.2018, 16:10 22
Доступ к закрытому ключу точно есть?
0
0 / 0 / 0
Регистрация: 10.03.2012
Сообщений: 22
30.10.2018, 16:16 23
Сертификат скопирован в контейнер, в личный кабинет через него пускает, единственное пароль от токена просит каждый раз. Вы про это?

зы
просьба сильно не ругать с КП сталкиваюсь первый раз в жизни , и то косвенным образом.)
0
0 / 0 / 0
Регистрация: 10.03.2012
Сообщений: 22
31.10.2018, 09:55 24
Вываливается с такой ошибкой, в ключом походу все нормально, по крайней мере в BinarySecurityToken сертификат присутствует

C++
1
2
3
4
5
6
7
8
9
10
11
System.Reflection.TargetInvocationException: Адресат вызова создал исключение. ---> System.NullReferenceException: В экземпляре объекта не задана ссылка на объект.
   в System.Security.Cryptography.Xml.Reference.CalculateHashValue(XmlDocument document, CanonicalXmlNodeList refList)
   в System.Security.Cryptography.Xml.SignedXml.BuildDigestedReferences()
   в System.Security.Cryptography.Xml.SignedXml.ComputeSignature()
   в CryptoPro.Sharpei.Xml.CPSignedXmlDetour.ComputeSignature()
   --- Конец трассировки внутреннего стека исключений ---
   в System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
   в System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
   в System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
   в System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   в ClrBridgeImpl.InvokeClrInstanceMethod(ClrBridgeImpl* , ObjectWrapper* objectWrapper, Char* pszMethodName, Int32 argsLength, ObjectWrapper** arguments, Boolean* argsAreByRef, Boolean* isException)
0
11 / 11 / 1
Регистрация: 16.11.2011
Сообщений: 50
31.10.2018, 10:09 25
У Вас ошибка при подписи во всех запросах или только в конкретном, если во всех, то посмотрите в сторону FSSSignedXml, он должен найти подписываемый узел

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Собственная реализация поиска подписываемого узла
public 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", Vars.xmlns_wsu);
        var el = document.SelectSingleNode($"//*[@wsu:Id=\"{idValue}\"]", nsmgr);
        return el as XmlElement;
    }
}
0
0 / 0 / 0
Регистрация: 10.03.2012
Сообщений: 22
31.10.2018, 10:57 26
Проблема в том, что переопределить метод как в c# нет возможности в нашей ERP-системе, сборка подключаемая...
0
11 / 11 / 1
Регистрация: 16.11.2011
Сообщений: 50
31.10.2018, 11:13 27
Здесь я Вам не подскажу, реализацией на плюсах не занимался
0
0 / 0 / 0
Регистрация: 10.03.2012
Сообщений: 22
31.10.2018, 15:01 28
Итак, переписали класс SignedXML, скомпилировали .dll, и подсунули ее в нашу сборку, теперь подхватывает его хорошо, и документ формируется как надо, единственное не понимает
C#
1
reference = new System.Security.Cryptography.Xml.Reference("#OGRN_#######");
С пустым URI все отрабатывает отлично, но как начинаешь вбивать туда какое-то значение, сразу вываливается с ошибкой Неверный формат строки.
Насколько понимаю он ищет элемент Body с таким же OGRN, который мы указываем в SignedInfo и ищем его через FSSSignedXml .GetIdElement()
Танцы с бубном.
0
11 / 11 / 1
Регистрация: 16.11.2011
Сообщений: 50
31.10.2018, 15:11 29
Да, так, но могут подписывается разные элементы внутри boby, такие как
XML
1
<fil:ROW wsu:Id="ELN_xxx">
или
XML
1
<fil:TREAT_FULL_PERIOD wsu:Id="ELN_xxx_4_vk">
XML
1
<fil:TREAT_PERIOD wsu:Id="ELN_xxx_4_doc">
0
0 / 0 / 0
Регистрация: 10.03.2012
Сообщений: 22
31.10.2018, 15:27 30
Банально ошибка в форматировании строки FSSSignedXml .GetIdElement(). Почему-то не принимал знак $:

C#
1
var el = document.SelectSingleNode(String.Format("//*[@wsu:Id="{0}"]", idValue), nsmgr);
Поехали дальше
0
0 / 0 / 0
Регистрация: 10.03.2012
Сообщений: 22
01.11.2018, 09:20 31
При попытке отправить зашифрованный xml на сервер:

C#
1
2
System.Net.WebException: "Базовое соединение закрыто: Непредвиденная ошибка при передаче."
IOException: Проверка подлинности не пройдена из-за закрытия транспортного потока удаленной стороной.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
string oRequest = "";            
oRequest = encryptionXML.OuterXml;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("https://docs.fss.ru/WSInsurerCrypto/FileOperationsLnPort?WSDL");
req.Headers.Add("SOAPAction", "\"http://ru/ibs/fss/ln/ws/FileOperationsLn.wsdl/getPrivateLNData\"");
req.ContentType = "text/xml; charset=\"utf-8\"";
req.Accept = "text/xml";
req.Method = "POST";            
 
using (Stream stm = req.GetRequestStream())
{
using (StreamWriter stmw = new StreamWriter(stm))
{
 stmw.Write(oRequest);
}
}
WebResponse response = req.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader sr = new StreamReader(responseStream);
string str = sr.ReadToEnd();
File.WriteAllText("resp_txt.xml", str);
Не сталкивались?
0
11 / 11 / 1
Регистрация: 16.11.2011
Сообщений: 50
01.11.2018, 12:45 32
Нет, в C# при работе с wcf сервисом ФСС, я не использую HttpWebRequest, единственное, что бросается в глаза, это
https://docs.fss.ru/WSInsurerC... onsLnPort?WSDL у меня https://docs-test.fss.ru/WSLnC... ionsLnPort
0
0 / 0 / 0
Регистрация: 10.03.2012
Сообщений: 22
01.11.2018, 13:11 33
Проблема была в следующем, нужно указать протокол по которому уходит запрос(узнали через fiddler), единственное у нас .NET 3.5 и на нем отсутствует протокол TSL 1.2(а он появился начиная с .NET 4.5), пришлось писать собственную реализацию:
Код
System.Net.ServicePointManager::set_SecurityProtocol(FSS.FSSSignedXml::SecurityProtocolType_Tls12());

Что насчет адреса запроса, если отловить запрос из АРМ ФСС на получение ЭЛН, то можно увидеть совершенно другой адрес: https://docs.fss.ru/ws-insurer... nPort?WSDL. В C# все отлично работает у нас.
0
0 / 0 / 0
Регистрация: 30.10.2018
Сообщений: 2
07.11.2018, 07:00 34
Адреса для запросов можно найти на странице ФСС, сейчас все адреса переведены на работу по протоколу v11, соответственно это адреса https://docs-test.fss.ru/WSLnC... nPort?WSDL и https://docs-test.fss.ru/ws-in... nPort?WSDL
0
0 / 0 / 0
Регистрация: 10.03.2012
Сообщений: 22
14.11.2018, 19:38 35
Спасибо вам за пример! А у вас реализован процесс подписания и шифрования реестра?
0
0 / 0 / 0
Регистрация: 29.11.2018
Сообщений: 1
30.11.2018, 10:37 36
Скажите а где можно получить ключевую пару (приватный,публичный ключи) для работы с тестовым контуром ФСС (https://docs-test.fss.ru/ws-in... ort?WSDL)?

Я получил в тестовом УЦ КриптоПро (https://www.cryptopro.ru/solutions/test-ca),
Затем сформировал весь SOAP запрос (согласно спецификации http://cabinets-test.fss.ru/%D... 181112.doc)

ФСС отвечает мне:
...
- <S:Body wsu:Id="OGRN_1027739443236">
- <ns1:getPrivateLNDataResponse xmlns:ns1="http://ru/ibs/fss/ln/ws/FileOperationsLn.wsdl" xmlns:ns2="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
- <ns1:FileOperationsLnUserGetPrivateLNDataOut>
<ns1:REQUEST_ID>GETLNINS_4210000443_2018_11_30_00001</ns1:REQUEST_ID>
<ns1:STATUS>0</ns1:STATUS>
<ns1:MESS>ORA-20001: Отсутствует подпись головной организации</ns1:MESS>
</ns1:FileOperationsLnUserGetPrivateLNDataOut>
</ns1:getPrivateLNDataResponse>
</S:Body>
</S:Envelope>

Может ФСС не нравится мой ключ которым я подписал блок текста внутри body.

Поделитесь кто где брал ключи.
0
0 / 0 / 0
Регистрация: 09.04.2019
Сообщений: 2
02.09.2019, 14:34 37
DTri, а есть ли пример кода для использования с сертификатами ГОСТ-2012?
0
0 / 0 / 1
Регистрация: 02.10.2016
Сообщений: 13
25.10.2019, 07:56 38
Добрый день!

Опробовал подписание указанных болванок отсюда. В итоге 500 ошибка на сервере.
Подправил в CryptoTools ГОСТ при подписании XML (у меня 2012)
//signer.SignedInfo.SignatureMethod = CPSignedXml.XmlDsigGost3410UrlObsolete;
signer.SignedInfo.SignatureMethod = CPSignedXml.XmlDsigGost3410_2012_256Url;

Использовал обе болванки, указанные тут, пробовал создавать свой шаблон XML и читать с него. Никак не получается получить ответ.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
      public async Task<ActionResult> Index()
        {
            
            CryptHelper cryptHelper = new CryptHelper();
            X509Certificate2 cert = cryptHelper.SelectSertificat();
            CryptoPro.Sharpei.Gost3410_2012_256CryptoServiceProvider prov = (CryptoPro.Sharpei.Gost3410_2012_256CryptoServiceProvider)cert.PrivateKey;
            SecureString s = new SecureString();
            // заполняем пароль... например так
            // ...
            // и передаем его в провайдер.
            prov.SetContainerPassword(s);
            // если необходимо, то можно сразу и проверить пароль, например, так
            byte[] dummyHash = new byte[32];
            prov.SignHash(dummyHash);
            // если он не подойдет, то будет выведено окно КриптоПро с просьбой ввести другой пароль.
            // При необходимости используем этот сертификат со ссылкой на уже открытый и прогруженный ключ.
 
             XmlDocument doc = new XmlDocument();
            using (StreamReader sr = new StreamReader("D://temp//new_query_template.xml"))
            {
                string text = sr.ReadToEnd();
                doc.LoadXml(text);
            }
            XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
            ns.AddNamespace("soapenv", Vars.xmlns_soapenv);
            ns.AddNamespace("ds", Vars.xmlns_ds);
            ns.AddNamespace("wsse", Vars.xmlns_wsse);
            ns.AddNamespace("wsu", Vars.xmlns_wsu);
            ns.AddNamespace("xsd", Vars.xmlns_xsd);
            ns.AddNamespace("xsi", Vars.xmlns_xsi);
            //doc.LoadXml(Encoding.UTF8.GetString(Convert.FromBase64String(Vars.base64Template)));
            XmlNodeList ogrnNode = doc.GetElementsByTagName("ogrn", "http://ru/ibs/fss/ln/ws/FileOperationsLn.wsdl");
            if (ogrnNode != null && ogrnNode.Count == 1)
            {
                ogrnNode[0].InnerText = Vars.OGRN;
            }
            XmlNodeList bodyNode = doc.GetElementsByTagName("Body", Vars.xmlns_soapenv);
            if (bodyNode != null && bodyNode.Count == 1)
            {
                XmlElement body = bodyNode[0] as XmlElement;
                body.SetAttribute("xmlns:wsu", Vars.xmlns_wsu);
                body.SetAttribute("Id", Vars.xmlns_wsu, $"OGRN_{Vars.OGRN}");
                try
                {
                    CryptoTools.GenerateSecurity(doc, cert, "OGRN_" + Vars.OGRN);
                }
                catch (Exception ex)
                {
                    throw new Exception($"Не удалось подписать сообщение. {ex.Message}. {ex.InnerException?.Message ?? ""}");
                }
            }
            else
            {
                throw new Exception($"Не удалось найти подписываемый сегмент {$"OGRN_{Vars.OGRN}"} в сообщении.");
            }
            string oRequest = "";
            oRequest = doc.OuterXml;
           // System.Net.HttpWebRequest req = (System.Net.HttpWebRequest)WebRequest.Create("https://docs.fss.ru/WSInsurerCrypto/FileOperationsLnPort?WSDL");
            System.Net.HttpWebRequest req = (System.Net.HttpWebRequest)WebRequest.Create("https://docs.fss.ru/ws-insurer-crypto-v11/FileOperationsLnPort?WSDL");
            req.Headers.Add("SOAPAction", "\"http://ru/ibs/fss/ln/ws/FileOperationsLn.wsdl/getPrivateLNData\"");
 
            //System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
            req.ContentType = "text/xml; charset=\"utf-8\"";
            req.Accept = "text/xml";
            req.Method = "POST";
 
            using (Stream stm = req.GetRequestStream())
            {
                using (StreamWriter stmw = new StreamWriter(stm))
                {
                    stmw.Write(oRequest);
                }
            }
            try
            {
                WebResponse response = req.GetResponse();
                Stream responseStream = response.GetResponseStream();
                StreamReader sr = new StreamReader(responseStream);
                string str = sr.ReadToEnd();
            } catch (Exception e)
            {
 
            }
 
           return View();
}
 
public class CryptHelper
    {
        public X509Certificate2 SelectSertificat()
        {
            // Формуруем коллекцию отображаемых сертификатов.
            X509Store store = new X509Store("MY", StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
            X509Certificate2Collection collection =
                (X509Certificate2Collection)store.Certificates;
 
            // Отображаем окно выбора сертификата.
            X509Certificate2Collection scollection =
                X509Certificate2UI.SelectFromCollection(collection,
                "Выбор секретного ключа по сертификату",
                "Выберите сертификат соответствующий Вашему секретному ключу.",
                X509SelectionFlag.SingleSelection);
 
            // Проверяем, что выбран сертификат
            if (scollection.Count == 0)
            {
                Console.WriteLine("Не выбран ни один сертификат.");
                return null;
            }
 
            // Выбран может быть только один сертификат.
            X509Certificate2 found = scollection[0];
 
            // Получаем секретный ключ соответствующий данному сертификату.
            AsymmetricAlgorithm asym = found.PrivateKey;
            if (asym == null)
            {
                Console.WriteLine("Нет секретного ключа соответствующего искомому сертификату.");
                return null;
            }
 
            Console.WriteLine("Найден секретный ключ, соответствующего искомому сертификату.");
            return found;
        }
    }
 
class SelectMy
    {
        [STAThread]
        static void Main(string[] args)
        {
            
            // Формуруем коллекцию отображаемых сертификатов.
            X509Store store = new X509Store("MY", StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
            X509Certificate2Collection collection = 
                (X509Certificate2Collection)store.Certificates;
 
            // Отображаем окно выбора сертификата.
            X509Certificate2Collection scollection = 
                X509Certificate2UI.SelectFromCollection(collection, 
                "Выбор секретного ключа по сертификату", 
                "Выберите сертификат соответствующий Вашему секретному ключу.", 
                X509SelectionFlag.SingleSelection);
 
            // Проверяем, что выбран сертификат
            if (scollection.Count == 0)
            {
                Console.WriteLine("Не выбран ни один сертификат.");
                return;
            }
 
            // Выбран может быть только один сертификат.
            X509Certificate2 found = scollection[0];
 
            // Получаем секретный ключ соответствующий данному сертификату.
            AsymmetricAlgorithm asym = found.PrivateKey;
            if (asym == null)
            {
                Console.WriteLine("Нет секретного ключа соответствующего искомому сертификату.");
                return;
            }
 
            Console.WriteLine("Найден секретный ключ, соответствующего искомому сертификату.");
        }
    }
 
 public class CryptoTools
    {
        /// <summary>
        /// Генерация подписей данных в xml
        /// </summary>
        /// <param name="document">Сформированный soap запрос</param>
        /// <param name="Certificate">Сертификат, с помощью которого будет выполняться подпись</param>
        /// <param name="Uri">Uri подписываемого узла</param>
        /// <returns></returns>
        public static XmlElement GenerateSecurity(XmlDocument document, X509Certificate2 Certificate, string Uri)
        {
            XmlNodeList nodeList = null;
            XmlElement elSecurity = null;
            FSSSignedXml signer = new FSSSignedXml(document)
            {
                SigningKey = Certificate.PrivateKey
            };
            KeyInfo keyInfo = new KeyInfo();
            XmlElement keySecurityTokenReference = document.CreateElement("wsse", "SecurityTokenReference", Vars.xmlns_wsse);
            XmlElement keyReference = document.CreateElement("wsse", "Reference", Vars.xmlns_wsse);
            keyReference.SetAttribute("URI", $"#http://eln.fss.ru/actor/mo/{Vars.OGRN}");
            keySecurityTokenReference.AppendChild(keyReference);
            var keyInfoData = new KeyInfoNode(keySecurityTokenReference);
            keyInfo.AddClause(keyInfoData);
            signer.KeyInfo = keyInfo;
            // Создаем ссылку на подписываемый узел XML. В данном примере и в методических рекомендациях СМЭВ подписываемый узел soapenv:Body помечен идентификатором "body".
            Reference reference = new Reference($"#{Uri}");
            // Задаём алгоритм хэширования подписываемого узла - ГОСТ Р 34.11-94.
            reference.DigestMethod = "http://www.w3.org/2001/04/xmldsig-more#gostr3411";
            // Добавляем преобразование для приведения подписываемого узла к каноническому виду  по алгоритму http://www.w3.org/2001/10/xml-exc-c14n# в соответствии с методическими рекомендациями СМЭВ.
            reference.AddTransform(new XmlDsigExcC14NTransform());
            // Добавляем ссылку на подписываемый узел.
            signer.AddReference(reference);
            signer.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
#pragma warning disable CS0612 // Type or member is obsolete
             //signer.SignedInfo.SignatureMethod = CPSignedXml.XmlDsigGost3410UrlObsolete;
            signer.SignedInfo.SignatureMethod = CPSignedXml.XmlDsigGost3410_2012_256Url;
#pragma warning restore CS0612 // Type or member is obsolete
            // Вычисляем подпись.
            signer.ComputeSignature();
            // Получаем представление подписи в виде XML.
            XmlElement xmlDigitalSignature = signer.GetXml();
            // Находим Header
            nodeList = document.GetElementsByTagName("Header", Vars.xmlns_soapenv);
            if (nodeList.Count == 1)
            {
                // Добавление тега Security
                elSecurity = document.CreateElement("wsse", "Security", Vars.xmlns_wsse);
                elSecurity.SetAttribute("actor", Vars.xmlns_soapenv, $"http://eln.fss.ru/actor/mo/{Vars.OGRN}");
                elSecurity.SetAttribute("xmlns:wsu", Vars.xmlns_wsu);
                elSecurity.SetAttribute("xmlns:ds", Vars.xmlns_ds);
                nodeList[0].AppendChild(elSecurity);
            }
            XmlNode nodeSecurity = (XmlNode)elSecurity;
            nodeSecurity.AppendChild(xmlDigitalSignature);
            XmlElement elBinarySecurityToken = document.CreateElement("wsse", "BinarySecurityToken", Vars.xmlns_wsse);
            elBinarySecurityToken.SetAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
            elBinarySecurityToken.SetAttribute("ValueType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3");
            elBinarySecurityToken.SetAttribute("Id", Vars.xmlns_wsu, $"http://eln.fss.ru/actor/mo/{Vars.OGRN}");
            elBinarySecurityToken.InnerText = Convert.ToBase64String(Certificate.Export(X509ContentType.Cert));
            nodeSecurity.AppendChild(elBinarySecurityToken);
 
            return elSecurity;
        }
 
        public void TestTestTest()
        {
            
        }
    }
    public class Vars
    {
        public const string xmlns_soapenv = "http://schemas.xmlsoap.org/soap/envelope/";
        public const string xmlns_xsd = "http://www.w3.org/2001/XMLSchema";
        public const string xmlns_xsi = "http://www.w3.org/2001/XMLSchema-instance";
        public const string xmlns_wsse = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
        public const string xmlns_wsu = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
        public const string xmlns_ds = "http://www.w3.org/2000/09/xmldsig#";
        public const string xmlns_eln = "http://ru/ibs/fss/ln/ws/FileOperationsLn.wsdl";
        public const string xmlns_xenc = "http://www.w3.org/2001/04/xmlenc#";
        public const string xmlns_sch = "http://gost34.ibs.ru/WrapperService/Schema";
        //public const string base64Template = "PHM6RW52ZWxvcGUgeG1sbnM6cz0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvc29hcC9lbnZlbG9wZS8iPg0KICA8cz pIZWFkZXI+DQogICAgPEFjdGlvbiBzOm11c3RVbmRlcnN0YW5kPSIxIiB4bWxucz0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA1LzA1L2 FkZHJlc3Npbmcvbm9uZSI+aHR0cDovL3J1L2licy9mc3MvbG4vd3MvRmlsZU9wZXJhdGlvbnNMbi53c2RsL2dldE5ld0xOTnVtPC9BY3Rpb24+DQogIDwvcz pIZWFkZXI+DQogIDxzOkJvZHkgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeG1sbnM6eHNkPSJodHRwOi 8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSI+DQogICAgPGdldE5ld0xOTnVtIHhtbG5zPSJodHRwOi8vcnUvaWJzL2Zzcy9sbi93cy9GaWxlT3BlcmF0aW 9uc0xuLndzZGwiPg0KICAgICAgPG9ncm4+PC9vZ3JuPg0KICAgIDwvZ2V0TmV3TE5OdW0+DQogIDwvczpCb2R5Pg0KPC9zOkVudmVsb3BlPg==";
        public const string base64Template = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHNvYXBlbnY6RW52ZWxvcGUgeG1sbnM6c29hcGVudj0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvc29hcC9lbnZlbG9wZS8iPgogIDxzb2FwZW52OkhlYWRlcj4KICA8L3NvYXBlbnY6SGVhZGVyPgogIDxzb2FwZW52OkJvZHkgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeG1sbnM6eHNkPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSI+CiAgICA8Z2V0UHJpdmF0ZUxORGF0YSB4bWxucz0iaHR0cDovL3J1L2licy9mc3MvbG4vd3MvRmlsZU9wZXJhdGlvbnNMbi53c2RsIj4KICAgICAgPHJlZ051bT41MzIwMDAwNDk5PC9yZWdOdW0+CiAgICAgIDxsbkNvZGU+OTEwMDAwMjczNjA5PC9sbkNvZGU+CiAgICAgIDxzbmlscz4xNDc1NDczNzk5OTwvc25pbHM+CiAgICA8L2dldFByaXZhdGVMTkRhdGE+CiAgPC9zb2FwZW52OkJvZHk+Cjwvc29hcGVudjpFbnZlbG9wZT4=";
        public const string OGRN = "1028900624576"; // ОГРН субъекта
    }
 
    // Собственная реализация поиска подписываемого узла
    public 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", Vars.xmlns_wsu);
            var el = document.SelectSingleNode($"//*[@wsu:Id=\"{idValue}\"]", nsmgr);
            return el as XmlElement;
        }
    }
Может кто-нибудь поделиться рабочим примером на C#?
0
0 / 0 / 0
Регистрация: 09.04.2019
Сообщений: 2
20.01.2020, 17:06 39
Вот такой код у меня работает с ГОСТ2012 и КриптоПро.Нет:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
using CryptoPro.Sharpei;
using CryptoPro.Sharpei.Xml;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using GostCryptography;
using GostCryptography.Xml;
 
namespace FssInfo {
    class CryptoTools {
        public static XmlElement GenerateSecurity(XmlDocument document,
                                            X509Certificate2 certificate,
                                            string prefix,
                                            string id,
                                            string iteration = "") {
            XmlNodeList nodeList = null;
            XmlElement elemSecurity = null;
            FSSSignedXml signer = new FSSSignedXml(document);
            signer.SigningKey = certificate.PrivateKey;
 
            KeyInfo keyInfo = new KeyInfo();
            XmlElement keySecurityTokenReference =
                document.CreateElement("wsse", "SecurityTokenReference", WsdlServiceHandle.xmlns_wsse);
            XmlElement keyReference = document.CreateElement("wsse", "Reference", WsdlServiceHandle.xmlns_wsse);
            keyReference.SetAttribute("URI", $"#http://eln.fss.ru/actor/mo/{WsdlServiceHandle.ogrn}");
            keySecurityTokenReference.AppendChild(keyReference);
            KeyInfoNode keyInfoData = new KeyInfoNode(keySecurityTokenReference);
            keyInfo.AddClause(keyInfoData);
            signer.KeyInfo = keyInfo;
 
            Reference reference =
                new Reference($"#{prefix}_{id}{(String.IsNullOrEmpty(iteration) ? "" : $"_{iteration}")}");
            reference.DigestMethod = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256"; //new!
            //reference.DigestMethod = "http://www.w3.org/2001/04/xmldsig-more#gostr3411";
            reference.AddTransform(new XmlDsigC14NTransform());
            signer.AddReference(reference);
            signer.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigC14NTransformUrl;
#pragma warning disable CS0612
            signer.SignedInfo.SignatureMethod = CPSignedXml.XmlDsigGost3410_2012_256Url;
            //signer.SignedInfo.SignatureMethod = CPSignedXml.XmlDsigGost3410UrlObsolete;
#pragma warning restore CS0612
            signer.ComputeSignature();
 
            XmlElement xmlDigitalSignature = signer.GetXml();
            nodeList = document.GetElementsByTagName("Header", WsdlServiceHandle.xmlns_soapenv);
            if (nodeList != null && nodeList.Count == 1) {
                elemSecurity = document.CreateElement("wsse", "Security", WsdlServiceHandle.xmlns_wsse);
                elemSecurity.SetAttribute(
                    "actor", WsdlServiceHandle.xmlns_soapenv, $"http://eln.fss.ru/actor/mo/{WsdlServiceHandle.ogrn}");
                elemSecurity.SetAttribute("xmlns:wsu", WsdlServiceHandle.xmlns_wsu);
                elemSecurity.SetAttribute("xmlns:ds", WsdlServiceHandle.xmlns_ds);
                nodeList[0].AppendChild(elemSecurity);
            }
 
            XmlNode nodeSecurity = (XmlNode)elemSecurity;
            nodeSecurity.AppendChild(xmlDigitalSignature);
            XmlElement elemBinarySecurityToken =
                document.CreateElement("wsse", "BinarySecurityToken", WsdlServiceHandle.xmlns_wsse);
            elemBinarySecurityToken.SetAttribute(
                "EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
            elemBinarySecurityToken.SetAttribute(
                "ValueType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3");
            elemBinarySecurityToken.SetAttribute(
                "Id", WsdlServiceHandle.xmlns_wsu, $"http://eln.fss.ru/actor/mo/{WsdlServiceHandle.ogrn}");
            elemBinarySecurityToken.InnerText = Convert.ToBase64String(certificate.Export(X509ContentType.Cert));
            nodeSecurity.AppendChild(elemBinarySecurityToken);
 
            return elemSecurity;
        }
 
        public static XmlDocument EncryptionXML(XmlDocument document,
                                          X509Certificate2 certificateEncryption,
                                          X509Certificate2 certificateOpen) {
            XmlNode elementBody = document.GetElementsByTagName("Envelope", WsdlServiceHandle.xmlns_soapenv)[0];
 
            XmlDocument doc = new XmlDocument();
            XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
            ns.AddNamespace("soapenv", WsdlServiceHandle.xmlns_soapenv);
            ns.AddNamespace("xenc", WsdlServiceHandle.xmlns_xenc);
            ns.AddNamespace("ds", WsdlServiceHandle.xmlns_ds);
            ns.AddNamespace("sch", WsdlServiceHandle.xmlns_sch);
            ns.AddNamespace("wsse", WsdlServiceHandle.xmlns_wsse);
            ns.AddNamespace("wsu", WsdlServiceHandle.xmlns_wsu);
 
            MemoryStream newRequestStream = new MemoryStream();
            XmlWriter writer = XmlWriter.Create(
                newRequestStream, new XmlWriterSettings { Encoding = Encoding.UTF8 });
            writer.WriteStartDocument();
            writer.WriteStartElement("soapenv", "Envelope", WsdlServiceHandle.xmlns_soapenv);
            writer.WriteStartElement("soapenv", "Header", WsdlServiceHandle.xmlns_soapenv);
            writer.WriteEndElement();
            writer.WriteStartElement("soapenv", "Body", WsdlServiceHandle.xmlns_soapenv);
            writer.WriteRaw(elementBody.OuterXml);
            writer.WriteEndElement();
            writer.WriteEndElement();
            writer.WriteEndDocument();
            writer.Flush();
 
            string xmlText = Encoding.GetEncoding("UTF-8").GetString(newRequestStream.ToArray());
            XmlDocument xml = new XmlDocument();
            newRequestStream.Position = 0;
            xml.Load(newRequestStream);
            writer.Close();
 
            XmlElement elementToEncrypt =
                xml.GetElementsByTagName("Envelope", WsdlServiceHandle.xmlns_soapenv)[1] as XmlElement;
            EncryptedData edElement = new EncryptedData();
            edElement.Type = EncryptedXml.XmlEncElementUrl;
            edElement.EncryptionMethod = new EncryptionMethod(GostEncryptedXml.XmlEncGostNamespaceUrl + "gost28147"); //was XmlEncGost28147Url
            edElement.KeyInfo = new KeyInfo();
 
            using (Gost28147CryptoServiceProvider sessionKey = new Gost28147CryptoServiceProvider()) {
                sessionKey.CipherOid = "1.2.643.7.1.2.5.1.1"; //new
 
                EncryptedXml eXml = new EncryptedXml();
                byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, sessionKey, false);
                EncryptedKey ek = new EncryptedKey();
                byte[] encryptedKey = CPEncryptedXml.EncryptKey(
                    sessionKey, (Gost3410_2012_256)certificateEncryption.PublicKey.Key,
                    GostKeyWrapMethod.CryptoProKeyWrap); //was GOST3410 //was without method
 
                ek.CipherData = new CipherData(encryptedKey);
                ek.EncryptionMethod = new EncryptionMethod(GostEncryptedXml.XmlEncGostNamespaceUrl + "transport-gost2001"); //was CPEncryptedXml.XmlEncGostKeyTransportUrl
                KeyInfoX509Data data = new KeyInfoX509Data(certificateOpen);
                ek.KeyInfo.AddClause(data);
                edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek));
                edElement.CipherData.CipherValue = encryptedElement;
            }
 
            EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
 
            return xml;
        }
 
        public static string DecryptXml(string document, X509Certificate2 cert) {
            XmlDocument xmlDoc = new XmlDocument();
 
            xmlDoc.PreserveWhitespace = true;
            xmlDoc.LoadXml(document);
 
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
            nsmgr.AddNamespace("enc", "http://www.w3.org/2001/04/xmlenc#");
            XmlNodeList list = xmlDoc.SelectNodes("//enc:EncryptedData", nsmgr);
 
            EncryptedXml exml = new EncryptedXml(xmlDoc);
 
            if (list != null) {
                foreach (XmlNode node in list) {
                    XmlElement element = node as XmlElement;
                    EncryptedData encryptedData = new EncryptedData();
                    encryptedData.LoadXml(element);
 
                    SymmetricAlgorithm decryptionKey = GetDecryptionKey(exml, encryptedData, cert);
 
                    if (decryptionKey == null)
                        throw new Exception("Ключ для расшифрования сообщения не найден.");
 
                    byte[] decryptedData = exml.DecryptData(encryptedData, decryptionKey);
                    exml.ReplaceData(element, decryptedData);
                }
            }
 
            return xmlDoc.OuterXml;
        }
 
        private static SymmetricAlgorithm GetDecryptionKey(EncryptedXml exml, EncryptedData encryptedData, X509Certificate2 cert) {
            IEnumerator encryptedKeyEnumerator = encryptedData.KeyInfo.GetEnumerator();
 
            while (encryptedKeyEnumerator.MoveNext()) {
                KeyInfoEncryptedKey current = encryptedKeyEnumerator.Current as KeyInfoEncryptedKey;
                if (current == null)
                    continue;
 
                EncryptedKey encryptedKey = current.EncryptedKey;
                if (encryptedKey == null)
                    continue;
 
                KeyInfo keyInfo = encryptedKey.KeyInfo;
                IEnumerator srcKeyEnumerator = keyInfo.GetEnumerator();
 
                while (srcKeyEnumerator.MoveNext()) {
                    KeyInfoX509Data keyInfoCert = srcKeyEnumerator.Current as KeyInfoX509Data;
                    if (keyInfoCert == null)
                        continue;
 
                    AsymmetricAlgorithm alg = cert.PrivateKey;
                    Gost3410_2012_256 myKey = alg as Gost3410_2012_256;
                    //Gost3410 myKey = alg as Gost3410;
                    if (myKey == null)
                        continue;
 
                    return CPEncryptedXml.DecryptKeyClass(
                        encryptedKey.CipherData.CipherValue, 
                        myKey, 
                        encryptedData.EncryptionMethod.KeyAlgorithm);
                }
            }
 
            return null;
        }
 
        public static X509Certificate2 GetCertificate(StoreLocation storeLocation,
                                                StoreName storeName,
                                                string subjectDN) {
            X509Store store = new X509Store(storeName, storeLocation);
            store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
 
            X509Certificate2Collection found =
                store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, subjectDN, false);
 
            if (found.Count == 0)
                throw new Exception("!!! Сертификат не найден: " + subjectDN);
 
            if (found.Count > 1)
                throw new Exception("!!! Найдено больше одного сертификата по имени: " + subjectDN);
 
            return found[0];
        }
 
        public static List<string> GetStoreSertificatesList(StoreLocation location, StoreName name) {
            X509Store store = new X509Store(name, location);
            store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
 
            List<string> certs = new List<string>();
            foreach (X509Certificate2 cert in store.Certificates)
                certs.Add(cert.Subject);
 
            return certs;
        }
    }
}
0
0 / 0 / 1
Регистрация: 02.10.2016
Сообщений: 13
26.01.2021, 06:41 40
У всех получается получать ЭЛН по спецификации 2.0?
У меня не получается. Удавалось получать только тестовый ЭЛН с тестового контура 2.0 с подписанием без шифрования.
С шифрованием - не выходит, возникает 500 ошибка. Причем сегодня не работает даже без шифрования тот самый ЭЛН, который получал несколько дней назад (возникает исключение "404 Не найден". Что не найдено - URI или ЭЛН - непонятно).
Если получать по спецификации 1.1 - без проблем.
У кого работает по спецификации 2.0, какие там изменения в целом?
Техподдержка не помогает отвечая, что "Техническая поддержка не дает консультаций и решений по разработке сторонних приложений"
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.01.2021, 06:41

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

SOAP-сервис из WSDL - как добавить WS-Adressing
Есть веб-сервис (не мой, менять не могу), с помощью WSDL-файла сгенерил прокси-класс для...

Правка SOAP запросов через PHP
Возможно ли на php поймать SOAP запрос, поправить его и пробросить дальше? если можно, то как? ...

Нужно на Spring написать сервис логирования запросов Hibernate сучностей
Добрый день, Нужно на Spring написать сервис логирования запросов Hibernate сучностей....

SOAP и set_time_limit - Как работать с настройкой вообще и вместе с SOAP в частности
Не могу понять как работать с настройкой вообще и вместе с SOAP в частности. Есть код: &lt;?php...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.