如何在 C# 中使用 SHA2 正确签署 SOAP 消息? [英] How do I properly sign a SOAP message with SHA2 in C#?

查看:29
本文介绍了如何在 C# 中使用 SHA2 正确签署 SOAP 消息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对我使用的第三方服务有以下要求

I have the following requirements from a 3rd party service that I'm using

处理个人信息和其他敏感信息的交易数据使用传输层安全保护.网络服务消息将通过 https (HTTP over SSL) 传输,并且必须遵守 Web服务 (WS)-Security v1.1 标准.WS-Security 部分服务消息必须:

Transactions dealing with personal information and other sensitive data use transport layer security protection. The web service message will be transported over https (HTTP over SSL) and must adhere to Web Service (WS)-Security v1.1 standard. The WS-Security section of the service message must:

  • 使用 2048 位密钥大小通过 x.509 证书进行签名
  • 使用 SHA2 和 RSA 算法进行加密
  • 使用 C14 规范化.

我设法使用以下代码对我的消息进行签名

I managed to get my message signed with the following code

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 解析和添加新节点手动修改它.我不明白这些例子,我正在想办法告诉服务为我做这件事.我有一个来自下面第 3 方的请求签名应该是什么样子的示例.我在客户端或绑定类中看不到任何允许我更改签名算法等内容的内容.我该怎么做?

The problem is that my message is being signed with sha1 instead of sha2. I'm trying to sign my message properly but the examples I found online have you generate the soap message then manually modify it with XML parsing and adding new nodes. I don't understand these examples and I'm trying to figure out a way to tell the service to do it for me. I have a sample of what the request signature should look like from the 3rd party below. I don't see anything in the client or binding class that would allow me to change things like the signature algorithm. How would I go about doing this?

<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>

推荐答案

在这里工作就是最终的解决方案

Got it working here is the final solution

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();
    }
}

这篇关于如何在 C# 中使用 SHA2 正确签署 SOAP 消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆