Как правильно подписать сообщение SOAP с помощью SHA2 в С#?

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

Операции, связанные с личной информацией и другими конфиденциальными данные используют защиту безопасности транспортного уровня. Сообщение веб-службы будет передаваться через https (HTTP через SSL) и должен соответствовать веб- Сервис (WS)-Безопасность v1.1 стандарт. Раздел WS-Security служебное сообщение должно:

  • Быть подписанным сертификатом x.509 с использованием 2048-битного ключа.
  • Используйте SHA2 с алгоритмом RSA для шифрования
  • Используйте канонизацию C14.

Мне удалось подписать мое сообщение следующим кодом

someServiceRef.widjetClient client = null;

try
{
    X509Certificate2 signingCert = GetSigningCert();
    var bindings = new BasicHttpsBinding();
    bindings.Security.Mode = BasicHttpsSecurityMode.TransportWithMessageCredential;
    bindings.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.Certificate;

    client = new someServiceRef.widjetClient(
        bindings,
        new EndpointAddress(@"<URL OF SERVICE>"));

    client.ClientCredentials.ClientCertificate.Certificate = signingCert;
    client.ClientCredentials.ServiceCertificate.DefaultCertificate = signingCert;

    client.Open();

    var request = BuildRequest();

    var response = client.SayHello(request);

    Console.WriteLine(response);
}
finally
{
    if (client != null)
    {
        if (client.State == System.ServiceModel.CommunicationState.Faulted)
            client.Abort();
        else
            client.Close();
    }
}

Проблема в том, что мое сообщение подписывается sha1 вместо sha2. Я пытаюсь правильно подписать свое сообщение, но примеры, которые я нашел в Интернете, заставляют вас генерировать мыльное сообщение, а затем вручную изменять его с помощью синтаксического анализа XML и добавления новых узлов. Я не понимаю эти примеры и пытаюсь найти способ заставить службу сделать это за меня. У меня есть пример того, как должна выглядеть подпись запроса от третьей стороны ниже. Я не вижу ничего в клиенте или классе привязки, что позволило бы мне изменить такие вещи, как алгоритм подписи. Как мне это сделать?

<SOAP-ENV:Envelope xmlns:SOAP-ENV = "http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header>
        <wsse:Security xmlns:wsse = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" SOAP-ENV:mustUnderstand = "1">
            <wsse:BinarySecurityToken xmlns:wsu = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 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 = "XWSSGID-12324774331131695995061">XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</wsse:BinarySecurityToken>
            <ds:Signature xmlns:ds = "http://www.w3.org/2000/09/xmldsig#">
                <ds:SignedInfo>
                    <ds:CanonicalizationMethod Algorithm = "http://www.w3.org/2001/10/xml-exc-c14n#" />
                    <ds:SignatureMethod Algorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha2" />
                    <ds:Reference URI = "#XWSSGID-1232477437326-1352495766">
                        <ds:DigestMethod Algorithm = "http://www.w3.org/2000/09/xmldsig#sha2" />
                        <ds:DigestValue>XXXXXXXXXXXXXXXXXXXXXX</ds:DigestValue>
                    </ds:Reference>
                    <ds:Reference URI = "#XWSSGID-1232477437326-823787906">
                        <ds:DigestMethod Algorithm = "http://www.w3.org/2000/09/xmldsig#sha2" />
                        <ds:DigestValue>XXXXXXXXXXXXXXXXXXXXX</ds:DigestValue>
                    </ds:Reference>
                </ds:SignedInfo>
                <ds:SignatureValue>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</ds:SignatureValue>
                <ds:KeyInfo>
                    <wsse:SecurityTokenReference xmlns:wsse = "http://www.w3.org/2000/09/xmldsig#" xmlns:wsu = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsse:Id = "XWSSGID-1232477437311698965010">
                        <wsse:Reference URI = "#XWSSGID-12324774331131695995061" />
                        <ds:X509Data>
                            <ds:X509IssuerName>XXXXXXXXXXXXXXXXXXXXXXXXX</ds:X509IssuerName>
                            <ds:X509SerialNumber>XXXXXXXXXXXXXXXXXXX</ds:X509SerialNumber>
                        </ds:X509Data>
                    </wsse:SecurityTokenReference>
                </ds:KeyInfo>
            </ds:Signature>
            <wsu:Timestamp xmlns:wsu = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id = "XWSSGID-1232477437326-823787906">
                <wsu:Created>2009-01-20T18:50:37.233Z</wsu:Created>
                <wsu:Expires>2009-01-20T18:50:42.233Z</wsu:Expires>
            </wsu:Timestamp>
        </wsse:Security>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body xmlns:SOAP-ENV = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsu = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id = "XWSSGID-1232477437326-1352495766">
        BODY OF MESSAGE GOES HERE
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Sha2 составляет 256 SHA. Поэтому используйте следующее: learn.microsoft.com/en-us/dotnet/api/…

jdweng 11.12.2020 17:28

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

scottDeveloper 11.12.2020 17:35

Версия sha по умолчанию (sh1 или sha 256) зависит от версии Net. См. следующее: learn.microsoft.com/en-us/dotnet/framework/migration-guide/…

jdweng 11.12.2020 17:35

Это может вам помочь:social.msdn.microsoft.com/Forums/vstudio/en-US/…

Theobald Du 14.12.2020 10:35

@TheobaldDu да, это было частью этого. Я понял это 2 дня назад. выложу решение

scottDeveloper 15.12.2020 16:46
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
1 463
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Получилось, что это окончательное решение

someServiceRef.widjetClient client = null;

try
{
    X509Certificate2 signingCert = GetSigningCert();
    var bindings = new BasicHttpsBinding();
    bindings.Security.Mode = BasicHttpsSecurityMode.TransportWithMessageCredential;
    bindings.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.Certificate;
    bindings.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Basic256Sha256

    var elements = bindings.CreateBindingElements();
    elements.Find<SecurityBindingElement>().EnableUnsecuredResponse = true;
    var customBindings = new CustomBinding(elements);

    client = new someServiceRef.widjetClient(
        customBindings,
        new EndpointAddress(@"<URL OF SERVICE>"));

    client.ClientCredentials.ClientCertificate.Certificate = signingCert;
    client.ClientCredentials.ServiceCertificate.DefaultCertificate = signingCert;

    client.Open();

    var request = BuildRequest();

    var response = client.SayHello(request);

    Console.WriteLine(response);
}
finally
{
    if (client != null)
    {
        if (client.State == System.ServiceModel.CommunicationState.Faulted)
            client.Abort();
        else
            client.Close();
    }
}

Другие вопросы по теме