C#问题使用XAdES签署XML文档 [英] C# problem Signing XML documents with XAdES
问题描述
我有一个很大的问题,花了很多时间...
我需要用XAdES模板签名xml。我正在使用2个参考文献。问题是第二,如果我添加Transform,它将正常工作( signedXml.CheckSignature()
return True
) ,如果没有这个转换,它将返回 False
。
我甚至修改了这个项目( http://xadesnet.codeplex.com/ [ ^ ])但仍然是同样的问题。
我应该粘贴所有代码吗?
Hi, I have one big problem and spend a lot of time for this...
I need to sign xml with XAdES template. I am using 2 references. The problem is with second, if I add Transform, it will work fine (signedXml.CheckSignature()
return True
), without this transform it will return False
.
I even modified this project (http://xadesnet.codeplex.com/[^]) but still same problem.
Should I paste all code?
System.Security.Cryptography.Xml.Reference reference2;
System.Security.Cryptography.Xml.SignedXml signedXml;
...
reference2 = new Reference();
reference2.Type = "http://uri.etsi.org/01903/v1.1.1#SignedProperties";
reference2.Uri = "#SignedPropertiesId";
//reference2.AddTransform(new XmlDsigExcC14NTransform()); IF I COMMENT THIS LINE IT WONT WORK
signedXml.AddReference(reference2);
signedXml.ComputeSignature();
XmlElement xmlDigitalSignature = signedXml.GetXml();
xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
signedXml.CheckSignature(); //return false if dont use Transform in second REF
签名应该看起来像这样(所以,没有变换),它可以在一行中:
Signature should look like this one (so, without transforms), it can be all in one line:
<ds:Signature Id="SignatureId">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod>
<ds:Reference Type="http://www.gzs.si/shemas/eslog/racun/1.5#Racun" URI="#data">
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
<ds:DigestValue>gvhK+4+omtrJ6zIQrTlKse+H8P2s=</ds:DigestValue>
</ds:Reference>
<ds:Reference Type="http://uri.etsi.org/01903/v1.1.1#SignedProperties" URI="#SignedPropertiesId">
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
<ds:DigestValue>cmbsiUG07eZmIoZBTc1rs7TRUIqU=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>signature value...</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>cert...</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
<ds:Object>
<xds:QualifyingProperties Target="#SignatureId">
<xds:SignedProperties Id="SignedPropertiesId">
<xds:SignedSignatureProperties>
<xds:SigningTime>2011-09-05T09:11:24.268Z</xds:SigningTime>
<xds:SigningCertificate>
<xds:Cert>
<xds:CertDigest>
<xds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1">
</xds:DigestMethod>
<xds:DigestValue>Le0DZovyhX7oXFyNs/rc4DHjQ3Lo=</xds:DigestValue>
</xds:CertDigest>
<xds:IssuerSerial>
<ds:X509IssuerName>OU=svigen-ca,O=state-institutions,C=si</ds:X509IssuerName>
<ds:X509SerialNumber>994015377</ds:X509SerialNumber>
</xds:IssuerSerial>
</xds:Cert>
</xds:SigningCertificate>
<xds:SignaturePolicyIdentifier>
<xds:SignaturePolicyImplied>
</xds:SignaturePolicyImplied>
</xds:SignaturePolicyIdentifier>
</xds:SignedSignatureProperties>
</xds:SignedProperties>
</xds:QualifyingProperties>
</ds:Object>
</ds:Signature>
谢谢。
Thanks.
推荐答案
首先我到目前为止还没有使用过XAdES模板,所以这不是我认为最后的答案。似乎真的需要将XML转换为正常工作。
尝试添加xmlDoc.PreserveWhitespace = true。
不幸的是,这是我目前唯一的想法。
问候
first I don't have used XAdES template so far, so this is not a final answer I think. It seems it is really needed to transform your XML to work properly.
Try adding xmlDoc.PreserveWhitespace = true .
Unfortunately, just my only idea at the moment.
Regards
我使用 http://xadesnet.codeplex.com/ [ ^ ] ...
i使用时引用有问题 - > reference2.Uri =#SignPropertiesId;如果Uri是一些xml数据,它运行良好(作为我的第一个参考)
试试这个XML http://www.2shared.com/document/DilKQ4Fk/racun_1202017254742.html [^] [ ^ ],从中删除签名。
XAdESSignedXml:SignedXml
I use XAdESSignedXml class from http://xadesnet.codeplex.com/[^]...
i have problem with references when use -> reference2.Uri = "#SignedPropertiesId"; if Uri is some xml data it works well (as my first reference)
try on this XML http://www.2shared.com/document/DilKQ4Fk/racun_1202017254742.html[^][^], remove signature from it.
XAdESSignedXml : SignedXml
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography.Xml;
using System.Xml;
namespace TestProject1
{
internal sealed class XAdESSignedXml : SignedXml
{
private readonly List<dataobject> _dataObjects = new List<dataobject>();
public const string XadesSignaturePropertiesNamespace = "http://uri.etsi.org/01903/v1.1.1#SignedProperties";
public XAdESSignedXml(XmlDocument document) : base(document) { }
public override XmlElement GetIdElement(XmlDocument doc, string id)
{
if (String.IsNullOrEmpty(id)) return null;
XmlElement xmlElement = base.GetIdElement(doc, id);
if (xmlElement != null) return xmlElement;
//if (_dataObjects.Count == 0) return null;
foreach (DataObject dataObject in _dataObjects)
{
XmlElement nodeWithSameId = findNodeWithAttributeValueIn(dataObject.Data, "Id", id);
if (nodeWithSameId != null)
return nodeWithSameId;
}
if (KeyInfo != null)
{
XmlElement nodeWithSameId = findNodeWithAttributeValueIn(KeyInfo.GetXml().SelectNodes("."), "Id", id);
if (nodeWithSameId != null)
return nodeWithSameId;
}
return null;
}
public new void AddObject(DataObject dataObject)
{
base.AddObject(dataObject);
_dataObjects.Add(dataObject);
}
public XmlElement findNodeWithAttributeValueIn(XmlNodeList nodeList, string attributeName, string value)
{
if (nodeList.Count == 0) return null;
foreach (XmlNode node in nodeList)
{
XmlElement nodeWithSameId = findNodeWithAttributeValueIn(node, attributeName, value);
if (nodeWithSameId != null) return nodeWithSameId;
}
return null;
}
private XmlElement findNodeWithAttributeValueIn(XmlNode node, string attributeName, string value)
{
string attributeValueInNode = getAttributeValueInNodeOrNull(node, attributeName);
if ((attributeValueInNode != null) && (attributeValueInNode.Equals(value))) return (XmlElement)node;
return findNodeWithAttributeValueIn(node.ChildNodes, attributeName, value);
}
private string getAttributeValueInNodeOrNull(XmlNode node, string attributeName)
{
if (node.Attributes != null)
{
XmlAttribute attribute = node.Attributes[attributeName];
if (attribute != null) return attribute.Value;
}
return null;
}
}
}
</dataobject></dataobject>
和我的方法:
AND my method:
private string signEracun(string xml, X509Certificate2 certificate)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = false;
xmlDoc.LoadXml(xml);
#region signing
TestProject1.XAdESSignedXml signedXml = new TestProject1.XAdESSignedXml(xmlDoc);
signedXml.Signature.Id = "SignatureId";
#region object -> signatureProperties
XmlElement signaturePropertiesRoot;
XmlElement qualifyingPropertiesRoot;
string URI = "http://uri.etsi.org/01903/v1.1.1#";
qualifyingPropertiesRoot = xmlDoc.CreateElement("xds", "QualifyingProperties", URI);
qualifyingPropertiesRoot.SetAttribute("Target", "#SignatureId");
signaturePropertiesRoot = xmlDoc.CreateElement("xds", "SignedProperties", URI);
signaturePropertiesRoot.SetAttribute("Id", "SignedPropertiesId");
XmlElement SignedSignatureProperties = xmlDoc.CreateElement("xds", "SignedSignatureProperties", URI);
XmlElement timestamp = xmlDoc.CreateElement("xds", "SigningTime", URI);
timestamp.InnerText = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"); //2011-09-05T09:11:24.268Z
SignedSignatureProperties.AppendChild(timestamp);
XmlElement SigningCertificate = xmlDoc.CreateElement("xds", "SigningCertificate", URI);
XmlElement Cert = xmlDoc.CreateElement("xds", "Cert", URI);
XmlElement CertDigest = xmlDoc.CreateElement("xds", "CertDigest", URI);
SHA1 cryptoServiceProvider = new SHA1CryptoServiceProvider();
byte[] sha1 = cryptoServiceProvider.ComputeHash(certificate.RawData);
XmlElement DigestMethod = xmlDoc.CreateElement("xds", "DigestMethod", URI); DigestMethod.SetAttribute("Algorithm", SignedXml.XmlDsigSHA1Url);
XmlElement DigestValue = xmlDoc.CreateElement("xds", "DigestValue", URI); DigestValue.InnerText = Convert.ToBase64String(sha1);
CertDigest.AppendChild(DigestMethod);
CertDigest.AppendChild(DigestValue);
Cert.AppendChild(CertDigest);
XmlElement IssuerSerial = xmlDoc.CreateElement("xds", "IssuerSerial", URI);
XmlElement X509IssuerName = xmlDoc.CreateElement("ds", "X509IssuerName", "http://www.w3.org/2000/09/xmldsig#"); X509IssuerName.InnerText = certificate.IssuerName.Name;
XmlElement X509SerialNumber = xmlDoc.CreateElement("ds", "X509SerialNumber", "http://www.w3.org/2000/09/xmldsig#"); X509SerialNumber.InnerText = certificate.SerialNumber;
IssuerSerial.AppendChild(X509IssuerName);
IssuerSerial.AppendChild(X509SerialNumber);
Cert.AppendChild(IssuerSerial);
SigningCertificate.AppendChild(Cert);
SignedSignatureProperties.AppendChild(SigningCertificate);
signaturePropertiesRoot.AppendChild(SignedSignatureProperties);
qualifyingPropertiesRoot.AppendChild(signaturePropertiesRoot);
DataObject dataObject = new DataObject
{
Data = qualifyingPropertiesRoot.SelectNodes("."),
};
signedXml.AddObject(dataObject);
#endregion
// Add the key to the SignedXml document.
signedXml.SigningKey = certificate.PrivateKey;
KeyInfo keyInfo = new KeyInfo();
KeyInfoX509Data keyInfoX509Data = new KeyInfoX509Data(certificate, X509IncludeOption.ExcludeRoot);
keyInfo.AddClause(keyInfoX509Data);
signedXml.KeyInfo = keyInfo;
//Reference 1
Reference reference2 = new Reference();
reference2.Type = "http://www.gzs.si/shemas/eslog/racun/1.5#Racun";
reference2.Uri = "#data";
signedXml.AddReference(reference2);
//Reference 2
reference2 = new Reference();
reference2.Type = "http://uri.etsi.org/01903/v1.1.1#SignedProperties";
reference2.Uri = "#SignedPropertiesId";
//reference2.AddTransform(new XmlDsigExcC14NTransform());
signedXml.AddReference(reference2);
// Compute the signature.
signedXml.ComputeSignature();
// Get the XML representation of the signature and save
// it to an XmlElement object.
XmlElement xmlDigitalSignature = signedXml.GetXml();
xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
#endregion
//check XML signature, return false if dont use transorm in seckont reference
bool checkSign = signedXml.CheckSignature();
return xmlDoc.OuterXml;
}
$ b $bBjörnRanft感谢您的支持帮助。
问候
Björn Ranft thank you for your help.
Regards
我已经尝试过了,但同样的问题...
谢谢无论如何。
问候
I already try this, but same problem...
thank anyway.
Regards
这篇关于C#问题使用XAdES签署XML文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!