C#问题使用XAdES签署XML文档 [英] C# problem Signing XML documents with XAdES

查看:111
本文介绍了C#问题使用XAdES签署XML文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个很大的问题,花了很多时间...



我需要用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆