0

私はいくつかの XML ファイルに署名しようとしていますが、うまくいきましたが、署名を確認する方法が見つかりません。受信者サービスはそれを問題なく受け入れますが (xml)、署名にエラーが見つかりました。

Web サービスのドキュメントを確認したところ、署名値は 1 行あたり最大 76 文字であり、xml ファイルをロードまたは編集するたびに .whitespace を保持する必要があるとのことでした。

これは、一度出力された xml ファイルです (セキュリティのためにいくつかの値を編集しました) puu.sh/d6lwC/25eb2a0d02.png (2 つの署名値が間隔のない長い行になっていることに注意してください。

これは私がどのように見えるべきだと思うかです: 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

彼はどういうわけか、このコードでbase64の値をチャンクと76の長さで分割するphpを介して私の問題を解決することができました

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

どうすればc#でそれを達成できますか?

4

2 に答える 2

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 に答える