如何在C#中使用SHA2正确地对SOAP消息进行签名



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

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

  • 使用2048位密钥大小的x.509证书进行签名
  • 使用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签名的。我正在尝试正确地对消息进行签名,但我在网上找到的示例让您生成soap消息,然后通过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>

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

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

最新更新