对签名XML进行故障排除

时间:2018-07-27 20:04:51

标签: c# xml encryption cryptography

请帮助: 供应商需要签名的xml,并且在描述如何正确签名xml方面没有提供太多帮助。我正在发送以下xml:

@Slf4j
public class CustomRedirectFilter extends ZuulFilter {

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return FilterConstants.SEND_FORWARD_FILTER_ORDER;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        String requestUrl = ctx.getRequest().getRequestURL().toString();

        if (shouldBeRedirected(requestUrl)) {
            String redirectUrl = generateRedirectUrl(ctx.getRequest());
            sendRedirect(ctx.getResponse(), redirectUrl);
        }
        return null;
    }

    private void sendRedirect(HttpServletResponse response, String redirectUrl){
        try {
            response.setHeader(HttpHeaders.LOCATION, redirectUrl);
            response.setStatus(HttpStatus.MOVED_PERMANENTLY.value());
            response.flushBuffer();
        } catch (IOException ex) {
            log.error("Could not redirect to: " + redirectUrl, ex);
        }
    }

    private boolean shouldBeRedirected(String requestUrl) {
        // your logic whether should we redirect request or not
        return true;
    }

    private String generateRedirectUrl(HttpServletRequest request) {
        String queryParams = request.getQueryString();
        String currentUrl =  request.getRequestURL().toString() + (queryParams == null ? "" : ("?" + queryParams));
        // update url
        return updatedUrl;
    }
}

,并且我收到一条错误消息,指出存在肥皂错误SECU3504:数字签名验证失败。 ds:Signed Info签名的有效性:java.lang.NullPointerException。签名参考的有效性:#_2:是。 #_1:否。

这听起来像是我引用信封正文Id =“ _ 1”时出现问题。

这是我在标头中创建主体和安全性令牌引用之后用于签名xml的C#代码。

<SOAP-ENV:Envelope xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header><wsse:Security SOAP-ENV:mustUnderstand="1" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><wsse:SecurityTokenReference Id="_2"><wsse:Reference URI="#binarytoken" /></wsse:SecurityTokenReference></ds:KeyInfo><wsse:BinarySecurityToken EncodingType="wsse:Base64Binary" ValueType="wsse:X509v3" wsu:Id="binarytoken">removed for security</wsse:BinarySecurityToken><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /><Reference URI="#_2"><Transforms><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /><DigestValue>b3U301pqu017IPMBNIZ04dybZ+A=</DigestValue></Reference><Reference URI="#_1"><Transforms><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /><DigestValue>NLpGjn8jJ7RI/R4rVdiwZPRRyMU=</DigestValue></Reference></SignedInfo><SignatureValue>some signed value here</SignatureValue></Signature></wsse:Security></SOAP-ENV:Header><SOAP-ENV:Body wsu:Id="_1"><msg:CompanyMessage xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" xmlns:msg="companyNameSpace"><msg:Header><msg:Verb>get</msg:Verb><msg:Noun>CompanyFunction</msg:Noun><msg:Revision>1</msg:Revision><msg:Source>COMPANY</msg:Source><msg:UserID>USER</msg:UserID><msg:MessageID>123456789</msg:MessageID><msg:ReplayDetection><wsu:Created>2018-07-27T02:20:39-05:00</wsu:Created><wsse:Nonce>65b9a415-19d9-4090-8520-e1de12cc9721</wsse:Nonce></msg:ReplayDetection></msg:Header></msg:CompanyMessage></SOAP-ENV:Body></SOAP-ENV:Envelope>

非常感谢您的协助。

1 个答案:

答案 0 :(得分:1)

在为电信运营商工作时,我们有使用WS-Security且需要签名的类似服务。当我需要测试这些服务时,我遇到了同样的问题。当然,我们的合作伙伴也很难使用这些服务。

最后,我通过使用WCF使其正常工作(您至少需要.NET Framework 4.0):

第一步,您需要从提供的WSDL中导入Web服务描述,并对生成的代码进行更改:

您必须在ProtectionLevel = System.Net.Security.ProtectionLevel.Sign上添加ServiceContratAttribute,以告知WCF您需要对其进行签名:

[System.ServiceModel.ServiceContractAttribute(ProtectionLevel = System.Net.Security.ProtectionLevel.Sign, Namespace="http://ServiceProvider.someTelecom.fr/Services/Payment "
public interface GetPaymentPortType
{
…
}

然后您应该在app.config中使用以下customBinding

   <customBinding>
    <binding name="HTTPBinding_WSSecurity">
     <security enableUnsecuredResponse="true" authenticationMode="MutualCertificate"
      messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
      requireSignatureConfirmation="false">
      <localClientSettings maxClockSkew="00:10:00" />
      <localServiceSettings maxClockSkew="00:10:00" />
      <secureConversationBootstrap />
     </security>
     <textMessageEncoding messageVersion="Soap11" />
     <httpTransport />
    </binding>
    </customBinding>

最后,在致电Web服务之前,您还需要加载您的客户证书(以下.pfx格式的代码),以便对肥皂消息进行签名。

//Load the signature certificate
X509Certificate2 mycertificate = new X509Certificate2("SignatureCertificate.pfx", "[pfx protection password]");

//Create the wcf client from the given binding
MyServicePortTypeClient client = new MyServicePortTypeClient("HTTPBinding_WSSecurity");
client.Endpoint.Address = new System.ServiceModel.EndpointAddress(new Uri("http://xxxxxx/myService"), EndpointIdentity.CreateDnsIdentity("dns_name"));
//set the client ceritificate
client.ClientCredentials.ClientCertificate.Certificate = mycertificate;
//Call the service
client.Payment(xxx);

奖金: 如果使用的是自签名证书,请确保可以在服务提供商的服务器上验证该证书。否则,您应该使用提供商提供的证书。