2009-06-22 11 views
8

해시 (hash)하기 전에 XML에서 동일한 정규화 알고리즘을 수행하는 디지털 서명을 수행 할 때보 다 일부 XML을 직접 canonicalize 할 때 동일한 XML 문서의 두 가지 해시가 발생합니다. 디지털 서명 정규화에는 정규화 할 때 새로운 직접 문자 '\ n'과 공백 문자가 포함되며 직접 알고리즘에는 포함되지 않습니다.XML 정규화 알고리즘은 XML 디지털 서명의 일부로 호출 할 때보다 직접 호출 할 때 두 가지 차이점 결과를 제공합니까?

새 줄 문자 + 공백을 포함해도 정규화 사양에 포함되지 않습니까? 나는이 버전을 특별히보고있다. http://www.w3.org/TR/2001/REC-xml-c14n-20010315

무슨 일이 일어나는지 아는 사람이 있습니까? 내가 볼 수 있도록 xml 문서와 두 코드 구현을 모두 포함 시켰습니다.

이것은 정말로 나를 혼란스럽게하고 왜 내가 뭘 분명히 놓치고 있는지 알고 싶습니다.

<root> 
    <child1>some text</child1> 
    <child2 attr="1" /> 
</root> 

직접 정규화 코드

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml; 
using System.Security.Cryptography.Xml; 
using System.Security.Cryptography; 
using System.IO; 
using System.ComponentModel; 

namespace XML_SignatureGenerator 
{ 
    class XML_C14N 
    { 
     private String _filename; 
     private Boolean isCommented = false; 
     private XmlDocument xmlDoc = null; 

     public XML_C14N(String filename) 
     { 
      _filename = filename; 
      xmlDoc = new XmlDocument(); 
      xmlDoc.Load(_filename); 
     } 

     //implement this spec http://www.w3.org/TR/2001/REC-xml-c14n-20010315 
     public String XML_Canonalize(System.Windows.Forms.RichTextBox tb) 
     { 
      //create c14n instance and load in xml file 
      XmlDsigC14NTransform c14n = new XmlDsigC14NTransform(isCommented); 

      c14n.LoadInput(xmlDoc); 

      //get canonalised stream 
      Stream s1 = (Stream)c14n.GetOutput(typeof(Stream)); 
      SHA1 sha1 = new SHA1CryptoServiceProvider(); 
      Byte[] output = sha1.ComputeHash(s1); 

      tb.Text = Convert.ToBase64String(output); 

      //create new xmldocument and save 
      String newFilename = _filename.Substring(0, _filename.Length - 4) + "C14N.xml"; 
      XmlDocument xmldoc2 = new XmlDocument(); 
      xmldoc2.Load(s1); 
      xmldoc2.Save(newFilename); 

      return newFilename; 
     } 

     public void set_isCommented(Boolean value) 
     { 
      isCommented = value; 
     } 

     public Boolean get_isCommented() 
     { 
      return isCommented; 
     } 
    } 
} 

는 XML 디지털 서명 코드

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml; 
using System.Security.Cryptography; 
using System.Security.Cryptography.Xml; 

namespace XML_SignatureGenerator 
{ 
class xmlSignature 
    { 
     public xmlSignature(String filename) 
     { 
      _filename = filename; 
     } 

     public Boolean SignXML() 
     { 
      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); 
      XmlDocument xmlDoc = new XmlDocument(); 
      xmlDoc.PreserveWhitespace = true; 
      String fname = _filename; //"C:\\SigTest.xml"; 
      xmlDoc.Load(fname); 

      SignedXml xmlSig = new SignedXml(xmlDoc); 
      xmlSig.SigningKey = rsa; 

      Reference reference = new Reference(); 
      reference.Uri = ""; 

      XmlDsigC14NTransform env = new XmlDsigC14NTransform(false); 
      reference.AddTransform(env); 

      xmlSig.AddReference(reference); 
      xmlSig.ComputeSignature(); 

      XmlElement xmlDigitalSignature = xmlSig.GetXml(); 
      xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true)); 

      xmlDoc.Save(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "/SignedXML.xml"); 

      return true; 
     } 
     private String _filename; 
    } 
} 

모든 아이디어가 좋은 것입니다! 그것은 모두 C# 코드입니다. 사전

답변

7

XML 시그이 깨진 내 의견에서, 공백을 처리하는 방법에

감사합니다. 옳은 생각을 가진 사람들이 정규화라고 부르는 것이 무엇인지에 확실히 부합하지 않습니다. 공백을 변경하면 이 아닌이 다이제스트에 영향을 주지만 xmlsig에서는 영향을받습니다.

한 가지 가능한 해결 방법은 서명 생성 코드에 전달하기 전에 표준화 루틴을 통해 문서를 전달하는 것입니다. 그것은 훨씬 더 예측 가능한 것들을 만들어야합니다.

This article 일을 명확히하는 데 도움이 될 수 있습니다. 처음에 그렇게하지하면서 코드의 두 번째 조각처럼 보이는

+0

아, 문제는 C14n 알고리즘 자체가 아니기 때문에 xml-digital 서명 사양은 문서를 표준화하는 동안 남아있는 공백과 줄 바꿈 문자를 지정합니까? 이것은 내가 몰랐던 함정입니다. 서명자에게 전달하기 전에 xml을 canonocalize하는 것에 대한 제안을 시도 할 것입니다. 이것은 분명히 거꾸로 논리입니다. W3c는 모든 XML 문서를 canical 형식으로 가져오고 xml-digital 서명 사양에 모순되는 사양으로 출시되었습니다. 매우 이상하게 보입니다. 왜 그런지 알고 있니? 도움 주셔서 감사합니다. – Jon

0

당신은

xmlDoc.PreserveWhitespace = true; 

있습니다.

필자가 알고 있듯이 표준화 사양에서는 요소 사이의 공백을 유지해야하므로 두 행 모두에이 행을 포함시키는 것이 좋습니다.