Форум программистов, компьютерный форум, киберфорум
C#: Веб-сервисы, WCF
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.61/847: Рейтинг темы: голосов - 847, средняя оценка - 4.61
1 / 1 / 0
Регистрация: 16.12.2015
Сообщений: 1
.NET 4.x

Интеграция с ГИС ЖКХ. Подпись SOAP и защита канала по ГОСТ

16.12.2015, 11:46. Показов 175275. Ответов 999

Студворк — интернет-сервис помощи студентам
Здравствуйте!

Передо мной стоит задача интеграции с системой ГИС ЖКХ (https://dom.gosuslugi.ru/) программой, написанной на языке C#, .NET Framework 4
Данный сервис предоставляет SOAP веб-сервисы для приема и передачи информации, соединение защищается сертификатом по алгоритму ГОСТ. Каждый элемент внутри тела SOAP сообщения подписывается сигнатурой XAdES-BES.
На данный момент для осуществления защищённого соединения я использую «МагПро КриптоТуннель» (stunnel) со следующими настройками:
Конфигурация stunnel (stunnel.conf)
verify=2
client=yes
CAFile=CA-test2-cryptopro.pem
engine=gost
usb_eject=yes
sslVersion=TLSv1
taskbar=yes
DEBUG=7

[pseudo-https]
protocol = http
accept = 127.0.0.1:8754
connect = 54.76.42.99:60045
ciphers = GOST2001-GOST89-GOST89
TIMEOUTclose = 0
cert=test.pem
key=test.key

Для обмена SOAP сообщениями я использую стандартный сервис WCF с прокси-классами, сгенерированные из WSDL файлов. Для подписи SOAP сообщений сигнатурой использую ниже представленный класс:
C#. Класс для подписи исходного SOAP сообщения
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
class ServiceClientBehavior : IEndpointBehavior, IClientMessageInspector
{
    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        XmlDocument doc = new XmlDocument();
        MemoryStream ms = new MemoryStream();
        XmlWriter writer = XmlWriter.Create(ms);
        request.WriteMessage(writer);
        writer.Flush();
        ms.Position = 0;
        doc.Load(ms);
        
        SignXml(doc);
        
        ms.SetLength(0);
        writer = XmlWriter.Create(ms);
        doc.WriteTo(writer);
        writer.Flush();
        ms.Position = 0;
        XmlReader reader = XmlReader.Create(ms);
        request = Message.CreateMessage(reader, int.MaxValue, request.Version);
 
        return null;
    }
    
    void SignXml(XmlDocument doc)
    {
        doc.PreserveWhitespace = true;
 
        // Получение элемента из тела сообщения
        var requestNode = doc.DocumentElement.ChildNodes[1].ChildNodes[0];
        var signRequestNode = SignRequest(requestNode);
 
        var body = requestNode.ParentNode;
        body.RemoveChild(requestNode);
        body.AppendChild(signRequestNode);
    }
    XmlNode SignRequest(XmlNode reqNode)
    {
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.PreserveWhitespace = true;
        xmlDoc.AppendChild(xmlDoc.ImportNode(reqNode, true));
 
        var signedXml = new SignedXML(xmlDoc);
        signedXml.SigningKey = certificate.PrivateKey;
 
        KeyInfo keyInfo = new KeyInfo();
        keyInfo.AddClause(new KeyInfoX509Data(certificate));
        signedXml.KeyInfo = keyInfo;
 
        signedXml.Signature.Id = "SignatureId";
 
        #region Создание DataObject
        {
            XmlElement SignaturePropertiesRoot;
            XmlElement QualifyingPropertiesRoot;
            string xadesURI = "http://uri.etsi.org/01903/v1.3.2#";
            string dsURI = "http://www.w3.org/2000/09/xmldsig#";
 
            QualifyingPropertiesRoot = xmlDoc.CreateElement("xades", "QualifyingProperties", xadesURI);
            QualifyingPropertiesRoot.SetAttribute("Target", "#SignatureId");
 
            SignaturePropertiesRoot = xmlDoc.CreateElement("xades", "SignedProperties", xadesURI);
            SignaturePropertiesRoot.SetAttribute("Id", "SignedPropertiesId");
 
            XmlElement SignedSignatureProperties = xmlDoc.CreateElement("xades", "SignedSignatureProperties", xadesURI);
 
            XmlElement timestamp = xmlDoc.CreateElement("xades", "SigningTime", xadesURI);
            timestamp.InnerText = XmlConvert.ToString(DateTimeOffset.Now);
            SignedSignatureProperties.AppendChild(timestamp);
 
            XmlElement SigningCertificate = xmlDoc.CreateElement("xades", "SigningCertificate", xadesURI);
            XmlElement Cert = xmlDoc.CreateElement("xades", "Cert", xadesURI);
            XmlElement CertDigest = xmlDoc.CreateElement("xades", "CertDigest", xadesURI);
 
            XmlElement DigestMethod = xmlDoc.CreateElement("ds", "DigestMethod", dsURI); DigestMethod.SetAttribute("Algorithm", "http://www.w3.org/2001/04/xmldsig-more#gostr3411");
            XmlElement DigestValue = xmlDoc.CreateElement("ds", "DigestValue", dsURI); DigestValue.InnerText = ComputeGostHash(this.ClientCertificate.RawData);
            CertDigest.AppendChild(DigestMethod);
            CertDigest.AppendChild(DigestValue);
            Cert.AppendChild(CertDigest);
 
            XmlElement IssuerSerial = xmlDoc.CreateElement("xades", "IssuerSerial", xadesURI);
            XmlElement X509IssuerName = xmlDoc.CreateElement("ds", "X509IssuerName", dsURI); X509IssuerName.InnerText = GetIssuerName(certificate);
            XmlElement X509SerialNumber = xmlDoc.CreateElement("ds", "X509SerialNumber", dsURI); X509SerialNumber.InnerText = GetSerialNumber(certificate);
            IssuerSerial.AppendChild(X509IssuerName);
            IssuerSerial.AppendChild(X509SerialNumber);
            Cert.AppendChild(IssuerSerial);
 
            SigningCertificate.AppendChild(Cert);
            SignedSignatureProperties.AppendChild(SigningCertificate);
 
            SignaturePropertiesRoot.AppendChild(SignedSignatureProperties);
            QualifyingPropertiesRoot.AppendChild(SignaturePropertiesRoot);
            DataObject dataObject = new DataObject
            {
                Data = QualifyingPropertiesRoot.SelectNodes("."),
            };
            signedXml.AddObject(dataObject);
        }
        #endregion
 
        signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411";
        signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
 
        var reference = new Reference();
        reference.Uri = "#RequestId";
        reference.DigestMethod = "http://www.w3.org/2001/04/xmldsig-more#gostr3411";
        reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
        reference.AddTransform(new XmlDsigExcC14NTransform());
        signedXml.AddReference(reference);
 
        reference = new Reference();
        reference.Uri = "#SignedPropertiesId";
        reference.DigestMethod = "http://www.w3.org/2001/04/xmldsig-more#gostr3411";
        reference.Type = "http://uri.etsi.org/01903#SignedProperties";
        reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
        reference.AddTransform(new XmlDsigExcC14NTransform());
        signedXml.AddReference(reference);
 
        signedXml.ComputeSignature();
 
        XmlElement signatureNode = signedXml.GetXml();
        xmlDoc.DocumentElement.PrependChild(xmlDoc.ImportNode(signatureNode, true));
 
        if (!VerifyXml(xmlDoc))
            throw new Exception("Подпись не проходит проверку.");
        return reqNode.OwnerDocument.ImportNode(xmlDoc.DocumentElement, true);
    }
}

В результате после подписи элемента "exportNsiItemRequest" SOAP-сообщение выглядит следующим образом:
XML. Подписанное SOAP сообщение
XML
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
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Header>
        <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">urn:exportNsiItem</Action>
        <h:RequestHeader xmlns="http://dom.gosuslugi.ru/schema/integration/7.1.0.2/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:h="http://dom.gosuslugi.ru/schema/integration/7.1.0.2/">
            <Date>2015-12-16T16:12:47.9885439+10:00</Date>
            <MessageGUID>c7a1d946-9fcf-4ebc-9c08-20ebe81179cf</MessageGUID>
            <SenderID>387142bd-4ff7-4d15-ab09-18b3d99fd9bd</SenderID>
        </h:RequestHeader>
    </s:Header>
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <exportNsiItemRequest Id="RequestId" xmlns="http://dom.gosuslugi.ru/schema/integration/7.1.0.2/nsi/">
            <Signature Id="SignatureId" xmlns="http://www.w3.org/2000/09/xmldsig#">
                <SignedInfo>
                    <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
                    <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411" />
                    <Reference URI="#RequestId">
                        <Transforms>
                            <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                            <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                        </Transforms>
                        <DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411" />
                        <DigestValue>fpTlCLCz9/78q4Zpng9eAiCZuaHP51fCXfllN2TeFPw=</DigestValue>
                    </Reference>
                    <Reference URI="#SignedPropertiesId" Type="http://uri.etsi.org/01903#SignedProperties">
                        <Transforms>
                            <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                            <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                        </Transforms>
                        <DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411" />
                        <DigestValue>9sBDvpcyxJLVxibQGy280Rz/MlcESescb6k6MEGKreQ=</DigestValue>
                    </Reference>
                </SignedInfo>
                <SignatureValue>...</SignatureValue>
                <KeyInfo>
                    <X509Data>
                        <X509Certificate>...</X509Certificate>
                    </X509Data>
                </KeyInfo>
                <Object>
                    <xades:QualifyingProperties Target="#SignatureId" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#">
                        <xades:SignedProperties Id="SignedPropertiesId">
                            <xades:SignedSignatureProperties>
                                <xades:SigningTime>2015-12-16T16:13:13.4750017+10:00</xades:SigningTime>
                                <xades:SigningCertificate>
                                    <xades:Cert>
                                        <xades:CertDigest>
                                            <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" />
                                            <ds:DigestValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#">B2/4UjEeZwUG0c+mlEfnAZIy8mlbGpkOp4L+jPkgcVY=</ds:DigestValue>
                                        </xades:CertDigest>
                                        <xades:IssuerSerial>
                                            <ds:X509IssuerName xmlns:ds="http://www.w3.org/2000/09/xmldsig#">cn=CRYPTO-PRO Test Center 2,o=CRYPTO-PRO LLC,l=Moscow,c=RU,1.2.840.113549.1.9.1=support@cryptopro.ru</ds:X509IssuerName>
                                            <ds:X509SerialNumber xmlns:ds="http://www.w3.org/2000/09/xmldsig#">401416565317479933092244230678231137456309019</ds:X509SerialNumber>
                                        </xades:IssuerSerial>
                                    </xades:Cert>
                                </xades:SigningCertificate>
                            </xades:SignedSignatureProperties>
                        </xades:SignedProperties>
                    </xades:QualifyingProperties>
                </Object>
            </Signature>
            <RegistryNumber>221</RegistryNumber>
        </exportNsiItemRequest>
    </s:Body>
</s:Envelope>

Проблема заключается в том, что ответ от сервера приходит следующий:
ru.lanit.security.crypto.CryptoException : ЭП не прошла проверку: Invalid XML Signature
Текст ответного сообщения следующий:
XML. SOAP-ответ от сервера
XML
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
<soap:Envelope xmlns:ns2="http://dom.gosuslugi.ru/schema/integration/7.1.0.2/" xmlns:ns3="http://www.w3.org/2000/09/xmldsig#" xmlns:ns5="http://dom.gosuslugi.ru/schema/integration/7.1.0.2/nsi/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header>
        <ns2:ResultHeader>
            <ns2:Date>2015-12-16T09:14:28.819+03:00</ns2:Date>
            <ns2:MessageGUID>c7a1d946-9fcf-4ebc-9c08-20ebe81179cf</ns2:MessageGUID>
        </ns2:ResultHeader>
    </soap:Header>
    <soap:Body>
        <ns5:exportNsiItemResult Id="signed-data-container">
            <ds:Signature Id="xmldsig-3208628d-03cc-4576-895d-ea6d78b1b6dd" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <ds:SignedInfo>
                    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
                    <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411" />
                    <ds:Reference URI="#signed-data-container">
                        <ds:Transforms>
                            <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                            <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                        </ds:Transforms>
                        <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411" />
                        <ds:DigestValue>iqCeIlUfsqxdZRuMTjvYKWBTVOtSNrJIYledBG8LrWA=</ds:DigestValue>
                    </ds:Reference>
                    <ds:Reference Type="http://uri.etsi.org/01903#SignedProperties" URI="#xmldsig-3208628d-03cc-4576-895d-ea6d78b1b6dd-signedprops">
                        <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411" />
                        <ds:DigestValue>yASmvpbUBqEPr1Vp+qzYjXhzzXymC9ggqUZZ8GbBVkI=</ds:DigestValue>
                    </ds:Reference>
                </ds:SignedInfo>
                <ds:SignatureValue>...</ds:SignatureValue>
                <ds:KeyInfo>
                    <ds:X509Data>
                        <ds:X509Certificate>...</ds:X509Certificate>
                    </ds:X509Data>
                </ds:KeyInfo>
                <ds:Object>
                    <xades:QualifyingProperties Target="#xmldsig-3208628d-03cc-4576-895d-ea6d78b1b6dd" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#">
                        <xades:SignedProperties Id="xmldsig-3208628d-03cc-4576-895d-ea6d78b1b6dd-signedprops">
                            <xades:SignedSignatureProperties>
                                <xades:SigningTime>2015-12-16T09:14:28.870+03:00</xades:SigningTime>
                                <xades:SigningCertificate>
                                    <xades:Cert>
                                        <xades:CertDigest>
                                            <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411" />
                                            <ds:DigestValue>Sz5+eJyswooXj8h3A5bhMbPG61QPExSKXuw+ZLzyeQ8=</ds:DigestValue>
                                        </xades:CertDigest>
                                        <xades:IssuerSerial>
                                            <ds:X509IssuerName>cn=CRYPTO-PRO Test Center 2,o=CRYPTO-PRO LLC,l=Moscow,c=RU,1.2.840.113549.1.9.1=support@cryptopro.ru</ds:X509IssuerName>
                                            <ds:X509SerialNumber>401416477754091206680439394611221196150735163</ds:X509SerialNumber>
                                        </xades:IssuerSerial>
                                    </xades:Cert>
                                </xades:SigningCertificate>
                            </xades:SignedSignatureProperties>
                        </xades:SignedProperties>
                    </xades:QualifyingProperties>
                </ds:Object>
            </ds:Signature>
            <ns2:ErrorMessage>
                <ns2:ErrorCode>AUTH01105</ns2:ErrorCode>
                <ns2:Description>Ошибка формата подписи запроса</ns2:Description>
                <ns2:StackTrace>ru.lanit.hcs.integration.common.exception.OperationProcessorException: ЭП не прошла проверку: Invalid XML Signature</ns2:StackTrace>
            </ns2:ErrorMessage>
        </ns5:exportNsiItemResult>
    </soap:Body>
</soap:Envelope>


Подскажите пожалуйста:
1) Как сделать валидную подпись, которая будет проходить проверку сервером, используя WCF ?
2) Как с помощью средств CryptoPro.NET отказаться от использования «МагПро КриптоТуннель» ?
1
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.12.2015, 11:46
Ответы с готовыми решениями:

Интеграция с ГИС ЖКХ. Подпись SOAP и защита канала по ГОСТ (3)
Предыдущая тема: https://www.cyberforum.ru/web-services-wcf/thread1776736.html Кто нибудь знает откуда брать справочники NsiRef по...

Интеграция с ГИС ЖКХ. Подпись SOAP и защита канала по ГОСТ (5)
Предыдущая тема: https://www.cyberforum.ru/web-services-wcf/thread1840159.html И так мы Я и umatkot, Берёмся за реализацию всего этого...

Интеграция с ГИС ЖКХ. Подпись SOAP и защита канала по ГОСТ (4)
Предыдущая тема: https://www.cyberforum.ru/web-services-wcf/thread1800721.html Здравствуйте. Подскажите, пожалуйста: делаю getState...

999
 Аватар для hhmm
67 / 58 / 1
Регистрация: 01.04.2016
Сообщений: 346
24.05.2016, 15:21
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от NaGuWaL Посмотреть сообщение
А я так понимаю пример который выложен тут он работает в связве КриптоПро .NET + CSP?
Да.

Я проводил экперименты, можно ли обойтись без 'КриптоПро .NET Клиент'.
Для себя выяснил следующее: 'КриптоПро .NET Клиент' это надстройка над 'КриптоПро CSP' - без установленной 'КриптоПро CSP' отказывается ставиться.
А без 'КриптоПро .NET Клиент' .NET приложение не находит поставщика услуги шифрования по ГОСТ.

Но приложение можно отвязать от явной ссылки на CryptoPro.Sharpei.xxx.dll.
Для этого нужно немного изменить код представленный Araney: убрать приведение типа к Gost3410CryptoServiceProvider в методе GetXadesSignedXml():

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static XadesSignedXml GetXadesSignedXml(X509Certificate2 certificate, XmlDocument originalDoc, string signatureid/*, string privateKeyPassword*/)
    {
    // вариант 1 - оригинальный пример
    /*
    SecureString secureString = new SecureString();
    foreach (var ch in privateKeyPassword)
        {
        secureString.AppendChar(ch);
        }
 
    // Судя по всему это нужно чтобы каждый раз не вылезал запрос к паролю - неправильно
    Gost3410CryptoServiceProvider provider = (Gost3410CryptoServiceProvider) certificate.PrivateKey;
    provider.SetContainerPassword(secureString);
 
    XadesSignedXml signedXml = new XadesSignedXml(originalDoc);// { SigningKey = provider };
 
    signedXml.SigningKey =  provider;
    */
 
    // вариант 2 - без привязки к Sharpei 
    XadesSignedXml signedXml = new XadesSignedXml(originalDoc);
    signedXml.SigningKey = certificate.PrivateKey;
1
 Аватар для NaGuWaL
17 / 14 / 0
Регистрация: 22.04.2016
Сообщений: 287
24.05.2016, 15:29
hhmm, Благодарю за ответ!)

А я так понимаю пример который выложен тут он работает в связве КриптоПро .NET + CSP?

Добавлено через 4 минуты
hhmm, Тобишь, чтобы работать с гис жкх надо купить КриптоПро CSP и КриптоПро .NET ну и по всей видимости МагПро КриптоТуннель?

Добавлено через 1 минуту
hhmm, Да и нафига в конфиге прописан Прокси?

XML
1
2
3
4
5
  <system.net>
    <defaultProxy useDefaultCredentials="false">
      <proxy bypassonlocal="False" proxyaddress="http://192.168.130.233:3128" />
    </defaultProxy>
  </system.net>
0
 Аватар для hhmm
67 / 58 / 1
Регистрация: 01.04.2016
Сообщений: 346
24.05.2016, 15:35
Цитата Сообщение от NaGuWaL Посмотреть сообщение
чтобы работать с гис жкх надо купить КриптоПро CSP и КриптоПро .NET
Пока получается так, что да - это необходимый минимум


Цитата Сообщение от NaGuWaL Посмотреть сообщение
ну и по всей видимости МагПро КриптоТуннель?
Без туннеля можно обойтись, если заставить свое приложение шифровать данные на уровне транспорта.

Цитата Сообщение от NaGuWaL Посмотреть сообщение
Да и нафига в конфиге прописан Прокси?
Это 'МагПро КриптоТуннель'
1
 Аватар для NaGuWaL
17 / 14 / 0
Регистрация: 22.04.2016
Сообщений: 287
24.05.2016, 15:40
hhmm, Хм... Как интересно... А есть вариант заточить WCF - клиента под весь этот "Пример(Трэш)"
0
 Аватар для hhmm
67 / 58 / 1
Регистрация: 01.04.2016
Сообщений: 346
24.05.2016, 15:59
Цитата Сообщение от NaGuWaL Посмотреть сообщение
Хм... Как интересно... А есть вариант заточить WCF - клиента под весь этот "Пример(Трэш)"

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

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
/// <summary>
/// Получить Binding и EndpointAddress по имени Endpoint
/// с учетом того, что будет сторонний прокси-сервер для шифрования использоваться НЕ БУДЕТ
/// и все шифровать будем сами
/// </summary>
/// <param name="EndpointName">Название Endpoint</param>
/// <param name="TargetBinding">Результирующий Binding</param>
/// <param name="TargetEndpointAddress">Результирующий EndpointAddress</param>
/// <returns>true если все получилось</returns>
public bool GetBindingByEndpointNameWithoutProxy(string EndpointName, out System.ServiceModel.Channels.Binding TargetBinding, out System.ServiceModel.EndpointAddress TargetEndpointAddress)
    {
    TargetBinding = null;
    TargetEndpointAddress = null;
 
    #region Поиск
 
    ChannelEndpointElement TargetEndpoint = FindEndpoint(EndpointName);
 
    if (TargetEndpoint == null)
        {
        return false;
        }
 
    TargetBinding = FindBinding(TargetEndpoint);
 
    if (TargetBinding == null)
        {
        return false;
        }
 
    #endregion Поиск
 
    #region Создание EndpointAddress
 
    // заменяем http на https
    Uri OriginalAddress = TargetEndpoint.Address;
    UriBuilder builder = new UriBuilder(OriginalAddress);
    builder.Scheme = "https";
    // builder.Port=443;
    Uri modifiedAddress = builder.Uri;
 
    // нужно только для кривых тестовых сертификатов у которых Common Name не соответствует ОГРН
    string CommonName = CryptoCertificateHelper.GetSertificateAttribute(GuGlobals.Certificate, CryptoCertificateHelper.CertificateAttributes.CN);
    EndpointIdentity identity = EndpointIdentity.CreateDnsIdentity(CommonName);
 
    TargetEndpointAddress = new EndpointAddress(modifiedAddress, identity);
    //TargetEndpointAddress = new EndpointAddress(modifiedAddress);
 
    #endregion Создание EndpointAddress
 
    #region Настройка Binding
 
    BasicHttpBinding basicBinding = TargetBinding as BasicHttpBinding;
    if (basicBinding == null)
        {
        throw new InvalidOperationException("Не удается привести к BasicHttpBinding");
        }
 
    basicBinding.UseDefaultWebProxy = false;
 
    // шифрование на уровне транспорта
    basicBinding.Security.Mode = BasicHttpSecurityMode.Transport;
    basicBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
 
    // дополнительные настройки
    ConfigureBinding(TargetBinding);
 
    #endregion Настройка Binding
 
    return true;
    }
    
    
/// <summary>
/// Дополнительные настройки Binding из-за кривой конфигурации файлов конфигурации Ланита
/// В частности, увеличение размера буферов для принимаемого сообщения
/// </summary>
private void ConfigureBinding(System.ServiceModel.Channels.Binding TargetBinding)
    {
    if (TargetBinding == null)
        {
        throw new ArgumentNullException("TargetBinding", "TargetBinding cannot be a null reference");
        }
 
    BasicHttpBinding basicBinding = TargetBinding as BasicHttpBinding;
    if (basicBinding == null)
        {
        throw new InvalidOperationException("Не удается привести к BasicHttpBinding");
        }
 
    // пока в 5 раз
    const int INCREASE_SIZE = 5;
 
    basicBinding.MaxReceivedMessageSize = basicBinding.MaxReceivedMessageSize * INCREASE_SIZE;
    basicBinding.MaxBufferSize = basicBinding.MaxBufferSize * INCREASE_SIZE;
 
    const int MAXSTRINGCONTENTLENGTH = 1 * 1024 * 1024;
 
    if (basicBinding.ReaderQuotas.MaxStringContentLength < MAXSTRINGCONTENTLENGTH)
        {
        basicBinding.ReaderQuotas.MaxStringContentLength = MAXSTRINGCONTENTLENGTH;
        }
    }
0
 Аватар для NaGuWaL
17 / 14 / 0
Регистрация: 22.04.2016
Сообщений: 287
24.05.2016, 16:03
hhmm, Не я не проэто... Я про полноценный WCF клиент... не про этот пример подписи чистого soap'а... Я про вот это -
Миниатюры
Интеграция с ГИС ЖКХ. Подпись SOAP и защита канала по ГОСТ  
0
 Аватар для NaGuWaL
17 / 14 / 0
Регистрация: 22.04.2016
Сообщений: 287
24.05.2016, 16:08
hhmm, Грубо говоря есть у меня вот такое во приложение на котором я пытаюсь понять кишки этого МОНСТРА(api ГИС ЖКХ). На основе этих кишок создать своего внутреннего монстра выполняющего не только требования ФЗ РФ но и внутрикорпоративных бешеных идей руководства)))
Вложения
Тип файла: zip TestGIS.zip (4.77 Мб, 44 просмотров)
0
 Аватар для hhmm
67 / 58 / 1
Регистрация: 01.04.2016
Сообщений: 346
24.05.2016, 16:15
Цитата Сообщение от NaGuWaL Посмотреть сообщение
Не я не проэто...
Да нет, вы про то же, что и я, только пока не уловили мою мысль. У вас пятая строчка на картинке
написана как и во всех примерах - с использованием в конструкторе одного параметра - названия конечной точки.
У всех этих класов есть контруктор принимающий два параметра - binding и endpoint, что позволяет настраивать их внутри приложения программно и как результат отказаться от промежуточного шифрующего туннеля.

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
System.ServiceModel.Channels.Binding TargetBinding;
System.ServiceModel.EndpointAddress TargetEndpointAddress;
 
if (!GetBindingByEndpointNameWithoutProxy("RegOrgPort", out TargetBinding, out TargetEndpointAddress))
    {
    return false;
    }
    
// Критерий поиска
exportOrgRegistryRequestSearchCriteria[] sc = new exportOrgRegistryRequestSearchCriteria[1];
sc[0] = new exportOrgRegistryRequestSearchCriteria();
sc[0].Items = new[] { m_OgrnToSearch };
sc[0].ItemsElementName = new[] { ItemsChoiceType18.OGRN };
Request.SearchCriteria = sc;
Request.Id = Crypto.CryptoXadesBES.XADES_SIGNED_DATA_CONTAINER;
 
RegOrgPortsTypeClient Proxy = new RegOrgPortsTypeClient(TargetBinding, TargetEndpointAddress);
 
// настраиваем экземпляр класса клиента для работы
SoapPrepareQuery(Proxy.Endpoint, Proxy.ClientCredentials);
 
Proxy.exportOrgRegistry(header, Request, out Result);
 
 
где:
 
/// <summary>
/// Настоить экземпляр класса используемого для запроса
/// </summary>
/// <param name="Endpoint">Конечная точка</param>
/// <param name="ClientCredentials">'Верительные грамоты' клиентской стороны</param>
protected void SoapPrepareQuery(System.ServiceModel.Description.ServiceEndpoint Endpoint, System.ServiceModel.Description.ClientCredentials ClientCredentials)
    {
    SoapAddMessageFilter(Endpoint);
 
    // если  прокси не используется, то установить данные клиента
    if (!GuGlobals.UseProxy)
        {
        SoapSetClientCredentials(ClientCredentials);
        }
    }
    
    
/// <summary>
/// Устанавливает набор свойств для самодельного шифрованного соединения - без внешнего прокси
/// </summary>
/// <param name="ClientCredentials">'Верительные грамоты' клиентской стороны</param>
protected static void SoapSetClientCredentials(System.ServiceModel.Description.ClientCredentials ClientCredentials)
    {
    ClientCredentials.ClientCertificate.Certificate = GuGlobals.Certificate;
    ClientCredentials.ServiceCertificate.DefaultCertificate = GuGlobals.Certificate;
    ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
    ClientCredentials.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;
    }
0
6 / 5 / 0
Регистрация: 28.03.2016
Сообщений: 34
24.05.2016, 16:20
Народ привет всем! Кто уже работает с промышленными данными!?? Помогите крик о помощи, в тех. поддержку написали тоже... Кто как решил проблему когда грузим например дома к договору РСО или ЛС пачками по 1000 штук к договорам и по 100 лс . при возникающих ошибках запрос целиком отбивается сервером и ничего не грузится. что делать? по одному объекту грузить не реально 5сек на запрос 200,000 объектов!!! зачем эти разработчики делают такой ГЕМОРОЙ ВСЕМ! Зачем прирывать загрузку по ошибкам!!!??? С ОбъектыЖелищногоФонда и того хуже там вобще как я понял можно только по одному грузить!!! Дайте мне этих разработчиков!!!! я надеюсь они это читают!!!
0
 Аватар для NaGuWaL
17 / 14 / 0
Регистрация: 22.04.2016
Сообщений: 287
24.05.2016, 16:26
hhmm, Да я переживу наличие КриптоТоннеля... У меня проблема с подписью сообщений именно в WCF-клиенте, так сказать по феншую и по ГОСТ))) Я так думаю что, возможно, должно хватить переноса behavior'a но у меня КЛИЕНТ...

Добавлено через 2 минуты
mecanizm, Ну во первых, система как говорилось недавно Должна была разрабатываться 7лет... А мы в попыхах бежим и роняем свои яйца о которые поднявшись опять спотыкаемся... Ждёмс...
0
6 / 5 / 0
Регистрация: 28.03.2016
Сообщений: 34
25.05.2016, 10:57
Коллеги кто сталкивается с такой проблемой? <ns4:ErrorCode>EXP002002</ns4:ErrorCode>
<ns4:ErrorMessage>Превышено максимальное время обработки запроса</ns4:ErrorMessage>
как можно попобороть, без того медленно запросы идут еще и по таймауту отваливаются... не возможно отлаживать обмен!
0
 Аватар для NaGuWaL
17 / 14 / 0
Регистрация: 22.04.2016
Сообщений: 287
25.05.2016, 11:23
mecanizm, С каким тестовым сервером вы работаете?
0
6 / 5 / 0
Регистрация: 28.03.2016
Сообщений: 34
25.05.2016, 12:06
http://54.76.42.99:60045
0
0 / 0 / 0
Регистрация: 27.01.2016
Сообщений: 9
25.05.2016, 12:11
Цитата Сообщение от hhmm Посмотреть сообщение
// нужно только для кривых тестовых сертификатов у которых Common Name не соответствует ОГРН string CommonName = CryptoCertificateHelper.GetSertificateAt tribute(GuGlobals.Certificate, CryptoCertificateHelper.CertificateAttri butes.CN);
Можете подсказать, что конкретно достается в методе GetSertificateAttribute и в каком виде? С OID'ами или без?
Пробовал доставать X509Certificate.Subject с подменой на OID и без, получаю ошибку "не удалось установить защищенное соединение..."
0
 Аватар для hhmm
67 / 58 / 1
Регистрация: 01.04.2016
Сообщений: 346
25.05.2016, 13:01
Цитата Сообщение от Jinks Посмотреть сообщение
Можете подсказать, что конкретно достается в методе GetSertificateAttribute и в каком виде? С OID'ами или без?
CN в виде строки, тот же Subject как я понимаю.

Мне это нужно было, когда тестовый ключ сделали с CN/Subject = 'Вася' и ОГРН реальной организации.
В данном примере в строке string CommonName будет равно 'Вася'

Добавлено через 14 минут
Цитата Сообщение от Jinks Посмотреть сообщение
получаю ошибку "не удалось установить защищенное соединение..."
На заметку:

Если у вас на работе используется (нешифрующий) прокси типа Squid, он может вас не пускать наружу.
По умолчанию TLS/SSL на нестандартный порт Squid дропает.
0
476 / 239 / 114
Регистрация: 12.05.2016
Сообщений: 647
25.05.2016, 16:01
Цитата Сообщение от mecanizm Посмотреть сообщение
Коллеги кто сталкивается с такой проблемой? <ns4:ErrorCode>EXP002002</ns4:ErrorCode>
<ns4:ErrorMessage>Превышено максимальное время обработки запроса</ns4:ErrorMessage>
как можно попобороть, без того медленно запросы идут еще и по таймауту отваливаются... не возможно отлаживать обмен!

Та же самая байда, половина запросов отвечает <ns4:ErrorMessage>Превышено максимальное время обработки запроса</ns4:ErrorMessage>

Техсаппорт Ланита, как обычно, в глухой несознанке
0
6 / 6 / 0
Регистрация: 24.12.2015
Сообщений: 41
25.05.2016, 16:16
для вас же баги правят. ну бывают разные нештатные ситуации. как будто у вас 100% всегда всё работает. да и уверен что у вас не такие нагрузки на систему. и вот только не нужно мне заливать что денег вбухано много, а толку ноль. откуда вы знаете? хоть бы слово тут прочитал что после обновления исправилась ошибка, что саппорт ответил и всё заработало. только негатив. вам самим не противно?
0
 Аватар для hhmm
67 / 58 / 1
Регистрация: 01.04.2016
Сообщений: 346
25.05.2016, 16:57
Цитата Сообщение от Dr_Elvis Посмотреть сообщение
что денег вбухано много, а толку ноль. откуда вы знаете?
Так это на сайте Ланита написано, почитайте: Группа компаний ЛАНИТ - Государственная информационная система жилищно-коммунального хозяйства (ГИС ЖКХ)
Сроки проекта: 01.07.2014 - 01.01.2017

Там же: Замминистра связи: ГИС ЖКХ готова на 80%


А цена вопроса тоже есть в интернете, читаем на другом сайте, внизу статьи:
Минкомсвязи требует от коммунальщиков перейти на ГИС ЖКХ от «Почты России», угрожая штрафами и дисквалификацией

За услуги по ГИС ЖКХ «Ланит» получит 360,7 млн рублей

Добавлено через 18 минут
Цитата Сообщение от Dr_Elvis Посмотреть сообщение
что саппорт ответил и всё заработало
Так если заявку на то, что за неделю из примерно 200 лицевых счетов одного маленького ЖСК залилось 75, отправили на той неделе и ответа пока нет.

Цитата Сообщение от Dr_Elvis Посмотреть сообщение
уверен что у вас не такие нагрузки на систему
Dr_Elvis, вы не обижайтесь, мы же еще только разминаемся.

например, у меня есть одна из баз РКЦ:
145 услуг
440 тысяч лицевых счетов
12.6 миллионов связок лицевой счет-услуга для 178 контрагентов
1
476 / 239 / 114
Регистрация: 12.05.2016
Сообщений: 647
25.05.2016, 23:54
Цитата Сообщение от hhmm Посмотреть сообщение
например, у меня есть одна из баз РКЦ:
145 услуг
440 тысяч лицевых счетов
12.6 миллионов связок лицевой счет-услуга для 178 контрагентов
+1

Я вот тоже недоумеваю, у меня вот тоже 400 управляшек и 700 тыс. счетов, это около 10 млн записей для начислений каждый месяц. При том, что естественно начисления объединяются в пачки по лицевому счету и принципалу, всё равно выходит, что около миллиона SOAP запросов надо пропихнуть.

Я очень надеюсь, что на боевой базе скорость будет выше чем 10-20 секунд на один запрос (как на перспективном). Иначе придется возить данные в Ланит (или кто там будет саппортить эту систему после 1 января 2017) на флэшке. Ибо получается, что заливка данных за один месяц будет занимать три месяца.

Еще что поразило - походу механизм загрузки из файлов и веб сервисы делают совершенно разные команды, не связанные друг с другом. Ибо неоднократно натыкались уже, что поля необязательные в SOAP являются обязательными в эксель файлах и наоборот... я как-то более консистентной логики проверок ожидал.
0
0 / 0 / 0
Регистрация: 26.05.2016
Сообщений: 2
26.05.2016, 09:58
Ребята, а где можно взять хоть как-то работающий пример?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
26.05.2016, 09:58

.NET 4.x Интеграция с ГИС ЖКХ. Подпись SOAP и защита канала по ГОСТ (2)
Начало темы здесь: https://www.cyberforum.ru/web-services-wcf/thread1615223.html umatkot, Да, к этому и пришел....а на дворе 1 июля ...

Интеграция с ГИС ЖКХ и подпись SOAP без Крипто .NET и stunnel
Решил создать отдельную тему, так как в теме Интеграция с ГИС ЖКХ. Подпись SOAP и защита канала по ГОСТ (4) - C# WCF уже можно заблудиться....

Soap, Java, Гис ЖКХ
Добрый день! Имеет ли кто опыт работы с soap в Java? Поставлена задача наладить работу с ГИС ЖКХ, До этого не работал с SOAP, почитал все...

1С и ГИС ЖКХ. Интеграция
Доброго дня, коллеги! Я думаю многие слышали о такой ГИС, как ЖКХ. Друзья, сталкивался ли кто нибудь с задачей интеграции с этой...

Интеграция с ГИС ЖКХ (ГЖ). 400 Bad request
Вводная: 1. C#. Классы proxy для работы с API генерятся утилитой SvcUtil.exe из wsdl-ек. 2. При срабатывании форматно-логического...


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

Или воспользуйтесь поиском по форуму:
520
Закрытая тема Создать тему
Новые блоги и статьи
Модель по догадкам
anaschu 25.08.2026
Прошло две недели. Я уже рассказывал, как разговаривал с сотрудниками у сортировки и как понял, что главная ветка — не про приёмку, а про отбор. Но тогда я думал, что понял механику. На этой неделе я. . .
Запись в регистр сведений независимо от заполненности табличной части
Maks 25.08.2026
Реализация из решения ниже выполнена на нетиповом документе с несколькими табличными частями, разработанного в КА2. Задача: Обеспечить запись документа в регистр сведений независимо от. . .
Ноутбук Альфария
kumehtar 24.08.2026
Встретился тут в сети ноутбук Альфария, примарха Альфа-Легиона. Хотя возможно, это ноутбук Омегона, разумеется. Ну как вам?
Мастера простых решений
DevAlt 23.08.2026
В сишарп стэках winforms, да и wpf существует сложная система связывания источниках данных и элементов формы(текстовые поля и метки), опирается все это на технологию событий и мета. . .
Цена ошибки
DevAlt 23.08.2026
Человек я беспокойный и потому заинтересовался OCaml, в чате форсили функторы модулей как суперфичу. Пытаясь отдуплить концепт, наткнулся на тутор с простым примером. А главный принцип обучения от. . .
Сегодня суббота, 22.08.2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины.
zorxor 22.08.2026
Сегодня суббота, 22. 08. 2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины. Кто Я, откуда Я пришел и куда Я иду? Эти вопросы не оставляют меня ни на секунду. Жизнь на планете Земля. . .
Жизня: рисунок укладки багажа, сделанный клодом
anaschu 21.08.2026
Сделал 15 снимков, он по снимкам сделал схему.
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru