首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在计算签名之前指定xml文档中签名的位置?

如何在计算签名之前指定xml文档中签名的位置?
EN

Stack Overflow用户
提问于 2014-01-07 12:37:10
回答 1查看 1.1K关注 0票数 0

在尝试使用SignedXml在C#中对xml请求进行签名时,我能够生成签名和签名的xml请求,但是在发送此消息时,我将从webservice获得一条失败消息。错误状态:数据和摘要值不匹配。

深入研究后,我检查了我们在Java中开发的等价代码。代码生成的xml签名请求具有与我的C#代码不同的摘要值,并且该代码从webservice获得成功消息。

经过大量讨论和分析,使用我的webservice提供的测试工具,我们了解到:在使用ComputeSignature()之前,Digest值会根据您在请求中指定数字签名的位置而发生变化。但我无法找到一种方法,您可以通过指定的位置,然后计算签名。这是我的密码:

代码语言:javascript
复制
        /*=================*/
        //CODE to remove whitespaces from the xml before building the xmlDocument

        String thisLine = "";
        String xmlString = "";
        StreamReader br = new StreamReader(Server.MapPath("~/" + fp));
        while ((thisLine = br.ReadLine()) != null)
        {
            xmlString = xmlString + thisLine.Trim();
        }
        br.Close();
        Debug.WriteLine("new logic: " + xmlString);


        XmlDocument xmlDocument = new XmlDocument();
           xmlDocument.LoadXml(xmlString);

        /*================*/





        SignedXml signedXml = new SignedXml(xmlDocument);

        //XmlDsigExcC14NTransformUrl
        signedXml.SignedInfo.CanonicalizationMethod =                SignedXml.XmlDsigC14NTransformUrl;
        signedXml.SigningKey = cert.PrivateKey;

        signedXml.KeyInfo.AddClause(new System.Security.Cryptography.Xml.KeyInfoX509Data(cert));


        Reference tRef = new Reference("");
        /*
                    XmlDsigExcC14NTransform env = new XmlDsigExcC14NTransform();
                    //Transform transf = new XmlDsigEnvelopedSignatureTransform(false);
                    tRef.AddTransform(transf);
                    */

        XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
        tRef.AddTransform(env);


        signedXml.AddReference(tRef);
        signedXml.ComputeSignature();




        XmlElement xmlDsig = signedXml.GetXml();
        xmlDsig.SetAttribute("Id", "Signature-1");

        XmlElement rootNode = xmlDocument.DocumentElement;
        rootNode.AppendChild(xmlDsig);

        XmlTextWriter w = new XmlTextWriter(Server.MapPath("~/attrdigsig2.xml"), new UTF8Encoding(false));
        w.Formatting = Formatting.Indented;

        xmlDocument.WriteTo(w);
        w.Close();

这是我收到的签名请求:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<ns:User xmlns:ns="http://www.user.com">
  <ns:Username>1DDOagUser</ns:Username>
  <ns:Password>toyota12</ns:Password>
  <Signature Id="Signature-1" 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/2000/09/xmldsig#rsa-sha1" />
      <Reference URI="">
        <Transforms>
          <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <DigestValue>KEqvZWvpT3yYqMMJSTBmUKNIQw4=</DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue>YQ+81KnxwM9RibFpmS48Gbfdv7gBxgXrH6XWdoF+OZaUq+uJOOcuuC9KNmC4pkMs0V/LEw2WI6zjs9ML8kxAx3vcU/8jZ9/b8Z1EK7ndCcqDvkfBUpltHQy9FyP3AQyeFyK0SFvcyJCxvetc7uoJgYDvKUVU/ydqolw2ZbOXCHvN34SwbqGgGlBed++I7yk7KWIOWXsfjdSVwkuIyvEuVwxCmHHhxgjjfVaPnJMBY3D1Ali28d+rwKphT3dXdroEjXIedIK6lkrNOlHsaWZGYgJxNN08nN8bnNCe9QXapzHysSLnc3tkbJ1i2KjVHpLxwDfxFuuhWxh2sCKCoNvLgA==</SignatureValue>
    <KeyInfo>
      <X509Data>
        <X509Certificate>MIIC0TCCAbmgAwIBAgIGATDa3Nm5MA0GCSqGSIb3DQEBBQUAMBgxFjAUBgNVBAMTDVNPQVBCb3hDb25maWcwHhcNMDgwNjE4MTAyODAwWhcNMjEwNjE4MTAyODAwWjAYMRYwFAYDVQQDEw1TT0FQQm94Q29uZmlnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApLw4QAWqVmEr+CEo8Fp8WPq9Oo7BdnNOtMT5sUp0IN4NVvKmdI8ju3HsbnXzI7csNDzK6Feo19J/XLZk/Lr3Q4bLmmD+bMLFljiIgQ89+Bwc3mtyT1Rr4WBQUKnF8+8y65m2RebySelzgWIeZM72JoThSw85VBtyHvjlQnTAnfwX0NV7mH+kbQDi0c4Q4UZhKWFfb5L2tbjcknsG0k4De07qIw+RsGipkuNoFyI6BwwC0IERv48sacL30nWAOZMNDkm4S61aAYuzfMZySzPseU6BUdIdYAnITgj4tHRJZ93OYnn6LObEkYxobyGi6SULtBQQYzHKgeeyvru2Z1L7nQIDAQABoyEwHzAdBgNVHQ4EFgQUjq3/y0NF+tlUqwLc8SP4uV4/PK4wDQYJKoZIhvcNAQEFBQADggEBAAJvxTw5cc/32ahQ2TlBCrBNeHvji4QYItimkoqQa1EMyBSnx1FXNRyfJ9Da/20ZdIvIfJvIozIU0V/iFd7Hi+a2bZeMkN/ofvUh3QchHfkP/718JhcIvug3fctUX27ENHLRRU/rzMvKg40+H9BJoos6lu7qgAyayCRgKR5A/U3cSE9ZrYMGBNqy/mSIscZXhDJw0KATLHircXwRjpN+0lk+7/df5T8tc8wJOIvETCfDaQlDzXHw4jhQFydloMY4Tm4//VZTVVh1nzt2rVv52pHZGP8Shb9e5qS/QicBTVqysyVQEpYktRrrTwZcbq/65sV0lOao2JzZOuj3qvdJ4kw=</X509Certificate>
      </X509Data>
    </KeyInfo>
  </Signature>
</ns:User>

我得到的摘要值:KEqvZWvpT3yYqMMJSTBmUKNIQw4=

正确的摘要值(由Java代码生成并从webservice获得成功响应的值):aa4phJzO4YWc2ZQ1CG8HZ4cB1SA=

备注:要签名的xml是一个普通的xml,而不是SOAP请求。我对SOAP请求使用相同的签名逻辑,由它生成的响应被web服务接受(web服务包含这两种方法:1用于普通xml请求,1用于soap请求)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-14 11:42:04

我解决了这个问题。这与在向web服务URL发送签名请求时保留空白空间有关。因此,如果不添加PreserveWhitespace=true语句,发送给验证器的数据与已签名的数据基本上是不同的(因为它不包含空白空间)。因此,不同的哈希值会导致无效的签名错误。

下面是代码片段:

代码语言:javascript
复制
XmlDocument xpdoc = new XmlDocument { PreserveWhitespace = true };
            xpdoc.Load(@fpath);

            using (Stream stream = webRequest.GetRequestStream())
            {
                xpdoc.Save(stream); //writes the request body into the http web request stream 
            }

有人能帮我把答案标为已解决还是封闭吗?谢谢。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20971814

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档