2014-01-07 2 views
0

При попытке подписать запрос xml с помощью SignedXml в C# я могу сгенерировать подпись и подписанный запрос xml, но я получаю сообщение об ошибке из моего веб-сервиса при отправке этого сообщения. Ошибка: данные и digestvalue не совпадают.Как указать местоположение подписи в XML-документе ПЕРЕД вычислением подписи?

Копаем глубже, я проверил эквивалентный код, который у нас есть, который был разработан на Java. Запрос, подписанный xml, который генерирует код, имеет другое значение дайджеста, чем то, что генерирует мой код C#, и код Java получает сообщение об успешном завершении работы с веб-сервисом.

После большого обсуждения и анализа с помощью тестового инструмента, предоставляемого моим веб-сервисом, мы понимаем следующее: Значение дайджеста изменяется в зависимости от того, где вы указываете местоположение цифровой подписи в своем запросе, прежде чем использовать ComputeSignature(). Но я не могу найти способ, с помощью которого вы можете указать местоположение, прежде чем вычислять подпись. Вот мой код:

 /*=================*/ 
     //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(); 

Вот подписанный запрос я получаю:

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

Digest Значение я получаю: KEqvZWvpT3yYqMMJSTBmUKNIQw4=

Правильное значение дайджеста (тот, который порожден кодом Java и получение ответа успеха от webservice): aa4phJzO4YWc2ZQ1CG8HZ4cB1SA=

Примечания: xml, который должен быть подписан, является обычным xml, а не SOA P xml запрос. Я использовал одну и ту же логику подписи для XML-запроса SOAP, и полученный от него ответ был принят веб-службой (веб-служба содержит как методы: 1 для обычного запроса xml, так и 1 для запроса soap xml).

+0

Итак, вы хотите вычислить подпись и поместить ее в файл, для которого вы его вычислите? Похоже на бесконечную рекурсию ... – Sinatr

+0

@Sinatr Nope. Я помещаю его в другой файл, если внимательно изучить код. Я просто хочу указать местоположение, прежде чем ComputeSignature() произойдет. – Soumya

ответ

0

Я понял вопрос. Это было связано с сохранением пробелов при отправке подписанного запроса на URL-адрес веб-службы. Поэтому, если вы не добавляете оператор PreserveWhitespace = true, данные, которые отправляются верификатору, в основном различаются (поскольку он не содержит пробелы), чем данные, которые были подписаны. Следовательно, были получены разные значения хеширования, что привело к недопустимой ошибке сигнатуры.

Вот фрагмент кода:

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 
      } 

Может кто-то помочь мне с разметкой ответ решенной или закрыты? Благодарю.

Смежные вопросы