【问题标题】:Splitting base64 signature value in a xml signed file在 xml 签名文件中拆分 base64 签名值
【发布时间】:2014-11-26 16:13:07
【问题描述】:

我正在尝试签署一些 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-enveloped-rsa-sha1-digital-signature-of-xml-data-using-php

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

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

我如何用 c# 实现这一点?

【问题讨论】:

  • 我找到了这段代码并实现了它,但我无法拆分base64字符串的总数puu.sh/d6mtC/4f7306e9b9.png
  • 也许开始看看那些 php 函数真正做了什么,然后在 c# 中做 :-) rtrim 修剪字符串的右侧。 Chunk_split 每 76 个字符(由输入参数定义)拆分一个字符串,base64_encode 只是一个简单的 base64 编码。 :-) 结合起来,你会得到答案!
  • Karl,我同意,但我不确定它是否有效puu.sh/d6omi/e931d1a79d.png

标签: c# xml base64 xml-signature xml-dsig


【解决方案1】:

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

var bytes = Convert.FromBase64String(str);
return Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks);

【讨论】:

    【解决方案2】:

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

        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);
        }
    

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

    【讨论】:

    • 我现在正在检查它 string.Join("", str.Take(len)); string.Join("", str.Skip(j * len).Take(len)); string.Join("", str.Skip(div * len).Take(remainder)); 给我一个无效的参数错误,如果你想笑就尝试调试,这是我制作的糟糕代码. pastebin.com/5Rs64X0v
    • 我正在使用 .NET Framework 3.5,因为整个解决方案使用 VFP 2008,puu.sh/d6zv6/326a5fb6bb.png 是的,看起来它也是 3.5 puu.sh/d6zxa/5e13bebb97.png
    • 我设法让它工作了,现在我正在与这些线作斗争,你能帮我一把吗?我不习惯使用 XML pastebin.com/Na05WqVs 解决这个问题应该可以解决我所有的麻烦。
    • 你不能只使用 xmldocument.DocumentElement.SelectSingleNode(para).AppendChild(xmlDigitalSignature) 吗?
    • 无法插入指定节点作为该节点的次要有效元素,因为指定节点不正确puu.sh/d6Bec/50e5387aa6.png
    猜你喜欢
    • 2022-08-15
    • 2013-08-31
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-27
    • 1970-01-01
    相关资源
    最近更新 更多