0

我正在尝试签署一些 XML 文件,我设法做得很好,但我找不到检查签名的方法,接收器服务很好地接受它(xml),但它在签名上发现错误。

我检查了 Web 服务的文档,他们说,签名值每行最多可以有 76 个字符,每次加载或编辑 xml 文件时我都必须保留.whitespace。

这是我的 xml 文件一旦输出(我编辑了一些安全值)puu.sh/d6lwC/25eb2a0d02.png (请注意两个签名值如何是没有空格的长行。

这就是我认为它应该看起来的样子:puu.sh/d6lCV/48b0cc0cd7.png

这是应该按照服务文档的 xml 文件:puu.sh/d6ltJ/bd8e25a4b4.png

这是我的签名代码

     SignedXml signedXml = new SignedXml(xmldocument);
        signedXml.SigningKey = certificado.PrivateKey;
        Signature XMLSignature = signedXml.Signature;
        Reference reference = new Reference();
        reference.Uri = referenciaUri;
        XMLSignature.SignedInfo.AddReference(reference);
        KeyInfo keyInfo = new KeyInfo();
        keyInfo.AddClause(new RSAKeyValue((RSA)certificado.PrivateKey));
        keyInfo.AddClause(new KeyInfoX509Data(certificado));
        XMLSignature.KeyInfo = keyInfo;
        signedXml.ComputeSignature();
        XmlElement xmlDigitalSignature = signedXml.GetXml();
        xmldocument.DocumentElement.SelectSingleNode(para).AppendChild(xmldocument.ImportNode(xmlDigitalSignature, true));    

我的问题是:

如何在不损坏 xml 本身的其他核心值的情况下轻松拆分签名值的行,从而使 web 服务能够正确读取和验证 xml 文件的签名?

在此先感谢,并原谅我蹩脚的英语。

编辑:我发现了这个问题 https://stackoverflow.com/questions/24916486/how-to-do-envelope-rsa-sha1-digital-signature-of-xml-data-using-php

他以某种方式设法通过 php 将 base64 值按块和 76 长度与此代码拆分来解决我的问题

// Base64 encoding
$SignatureValue = rtrim(chunk_split(base64_encode($SignatureValue_bruto), 76));    

我怎样才能用 c# 实现这一点?

4

2 回答 2

1

有点老了,但我认为让 dotNet 像这样为您完成工作要简单得多:

var bytes = Convert.FromBase64String(str);
return Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks);
于 2017-02-13T14:40:24.377 回答
0

好的!你可以试试这个:-)添加以下代码

    public static string base64_encode(string str)
    {
        return System.Convert.ToBase64String(Encoding.UTF8.GetBytes(str));
    }

    public static string chunk_split(string str, int len)
    {
        var strings = new List<string>();
        var div = str.Length % len;
        var remainder = len - div * len;

        if (div == 1)
        {
            return string.Join("", str.Take(len));
        }

        for (var j = 0; j < div; j++)
        {
            var s = string.Join("", str.Skip(j * len).Take(len));
            if (!string.IsNullOrEmpty(s))
                strings.Add(s);
        }

        if (remainder > 0)
        {
            var s = string.Join("", str.Skip(div * len).Take(remainder));
            if (!string.IsNullOrEmpty(s))
                strings.Add(s);
        }

        return string.Join(Environment.NewLine, strings.ToArray());
    }

    public static string rtrim(string input)
    {
        while (input.EndsWith(Environment.NewLine))
            input = input.Remove(input.Length - Environment.NewLine.Length);

        return input.TrimEnd(' ');
    }

然后就用

chunk_split(base64_encode(strstr), 76);

编辑您可以使用此功能来修复文档的签名。我不知道我还能如何帮助你:P

    public static void UpdateXmlSignature(string filename)
    {
        // Load the target xml, the xml file with the certificate
        var doc = XDocument.Load(filename);
        var cert = doc.XPathSelectElement("//X509Data/X509Certificate");
        if (cert != null)
        {
            var updatedValue = rtrim(chunk_split(base64_encode(cert.Value), 76));
            cert.Value = updatedValue;
        }

        // Overwrite the old file
        doc.Save(filename);
    }

这将要求所有代码都已到位。

于 2014-11-26T18:37:49.320 回答