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