【问题标题】:signing a xml document with x509 certificate使用 x509 证书签署 xml 文档
【发布时间】:2014-06-17 03:52:23
【问题描述】:

每次我尝试发送签名的 XML 时,Web 服务验证程序都会拒绝它。

为了签署文件,我刚刚修改了微软提供的这个示例代码:

http://msdn.microsoft.com/es-es/library/ms229745(v=vs.110).aspx

我的实现:

    public static XmlDocument FirmarXML(XmlDocument xmlDoc)
    {
        try
        {
            X509Certificate2 myCert = null;
            var store = new X509Store(StoreLocation.CurrentUser); //StoreLocation.LocalMachine fails too
            store.Open(OpenFlags.ReadOnly);
            var certificates = store.Certificates;
            foreach (var certificate in certificates)
            {
                if (certificate.Subject.Contains("xxx"))
                {
                    myCert = certificate;
                    break;
                }
            }

            if (myCert != null)
            {
                RSA rsaKey = ((RSA)myCert.PrivateKey);

                // Sign the XML document. 
                SignXml(xmlDoc, rsaKey);                    
            }

        }
        catch (Exception e)
        {
            MessageBox.Show(e.Message);
        }
        return xmlDoc;
    }


    // Sign an XML file. 
    // This document cannot be verified unless the verifying 
    // code has the key with which it was signed.
    public static void SignXml(XmlDocument xmlDoc, RSA Key)
    {
        // Check arguments.
        if (xmlDoc == null)
            throw new ArgumentException("xmlDoc");
        if (Key == null)
            throw new ArgumentException("Key");

        // Create a SignedXml object.
        SignedXml signedXml = new SignedXml(xmlDoc);

        // Add the key to the SignedXml document.
        signedXml.SigningKey = Key;

        // Create a reference to be signed.
        Reference reference = new Reference();
        reference.Uri = "";

        // Add an enveloped transformation to the reference.
        XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
        reference.AddTransform(env);

        // Add the reference to the SignedXml object.
        signedXml.AddReference(reference);

        // Compute the signature.
        signedXml.ComputeSignature();

        // Get the XML representation of the signature and save
        // it to an XmlElement object.
        XmlElement xmlDigitalSignature = signedXml.GetXml();

        // Append the element to the XML document.
        xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));

    }

我想我正在使用自己的证书执行相同的步骤,但是它没有按预期工作。

欢迎提出任何建议。

【问题讨论】:

    标签: c# xml xml-signature x509


    【解决方案1】:

    服务器如何知道文档是用什么证书签名的?您似乎没有在签名文档中包含证书:

        KeyInfo keyInfo = new KeyInfo();
        KeyInfoX509Data keyInfoData = new KeyInfoX509Data( Key );
        keyInfo.AddClause( keyInfoData );
        signedXml.KeyInfo = keyInfo;
    

    如果您需要更多详细信息,请参阅我的博客条目

    http://www.wiktorzychla.com/2012/12/interoperable-xml-digital-signatures-c_20.html

    【讨论】:

    • 您好 Wiktor,您的博客非常有趣,我使用您展示的示例进行测试。不幸的是我仍然有同样的问题,签名被拒绝。我将在下面发布更多信息。
    • 只是想知道,这种方式不会在有效负载中公开私钥,还是私钥会在有效负载中以某种方式加密?
    • @Jami:这种方式没有包含私钥,只有公钥(证书)。
    【解决方案2】:

    这篇文章已经很久没有创建了。我遇到了同样的问题,无法验证数字签名。

    谁有同样的问题。就我而言,区别在于 XmlDocument.PreserveWhitespace 选项。

    PreserveWhitespace = true 时,文档对公钥进行检查时无效。 PreserveWhitespace = false 使签名的 XML 有效。

    我猜是在将签名的 XML 保存到文件并将其发送到服务器时。文档中插入了一些空格或特殊字符,使其无效。

    【讨论】:

    • 如果您想使用 PreserveWhitespace = true 将 xml 中的空格保留为原始格式,那么在验证 xml 时在服务器代码中,您也必须在加载 xml 时设置 PreserveWhitespace = true。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    • 2018-04-16
    • 1970-01-01
    • 2011-06-01
    • 2013-08-07
    • 1970-01-01
    相关资源
    最近更新 更多