3

政府の請求システム用のコードをいくつか作成していますが、数週間読んだ後、行き止まりになりました。

サーバーから受信した xml ファイル内の少なくとも 2 つの署名を検証する必要があります。私が証明書ファイルまたは x509store で署名しているときに署名を検証するために、パブリック MSDN に基づいていくつかのコードを作成し、正常に動作しました。問題なく、参照に基づいて各署名に署名および検証できます。

しかし、ファイルを受け取ったとき、証明書ファイルがないため、それを検証する方法がわかりません。内部にタグがあることは確かです。その値を取得してopenssl.exeに配置すると、確認できます署名者の身元ですが、署名が正しく行われたかどうかを確認する方法はわかりません

http://puu.sh/dypRH/c45e200202.png

過去に私が使用した

if (signedXml.CheckSignature(cert, true))

今、私はsignedXml.CheckSignature())を試します

毎回失敗します。どの署名を選択するかを参照できないため、for を作成しました

                foreach (XmlNode node1 in nodeList)
            {
                    testt = node1.OuterXml;
                     testt = testt.Replace(Environment.NewLine, string.Empty);
                    ttt.PreserveWhitespace = true;     
                    ttt.LoadXml(testt);

                    testt = testt.Replace(Environment.NewLine, string.Empty);
                   signedXml.LoadXml(ttt.DocumentElement);
                    //if (signedXml.CheckSignature(cert, true))
                    if (signedXml.CheckSignature())
                    {
                        Console.WriteLine("The XML signature is valid.");
                    }
                    else
                    {
                        Console.WriteLine("The XML signature is not valid.");
                    }


            #endregion
        }

それでも彼らは失敗する

また、xml ファイルに基づいて証明書を作成しました。

X509Certificate c = X509Certificate.CreateFromSignedFile("test.xml");
theCertificate = new X509Certificate2(c);

検証しますが、失敗します

私は今何をすべきか本当にわかりません、私はちょっと必死です、これがxmlファイルです

http://puu.sh/dyqcv/356dd289ae.xml

署名を検証する必要があります。この後、応答ファイルを作成してサーバーに送り返す必要があります (準備はできていますが、署名を検証できないため、先に進みたくありません)。

ああ、はい、私は名前空間を削除し、署名のチェック/計算の前にすべてを線形化しました

    public static XElement RemoveAllNamespaces(XElement e)
    {
        return new XElement(e.Name.LocalName,
           (from n in e.Nodes()
            select ((n is XElement) ? RemoveAllNamespaces(n as XElement) : n)),
           (e.HasAttributes) ? (from a in e.Attributes()
                                where (!a.IsNamespaceDeclaration)
                                select new XAttribute(a.Name.LocalName, a.Value)) : null);
    }

あらゆる種類の助けに心から感謝します。どこで試してみるべきかの小さな指針でも役立ちます。

ああ、申し訳ありませんが、私は本当にすべてのウェブサイトをチェックしました。この質問が繰り返されないことを願っています.

しかし、私は再び尋ねるのに十分な動機を持っていました

https://stackoverflow.com/questions/27158035/replace-string-with-another-string-does-not-work

これには苦労しました笑

よろしく!

編集: user409104 が尋ねたように、ここにファイル全体の署名値 (3 つのうちの 1 つ目) があり、署名ノードと keyinfo 値も含まれています

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="#SetDoc">
<Transforms>
<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>pIQ3XhBvaULXo7vPOktydkK+c3g=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>
n/bgCyPOI01quzrpt0OLRUbBnUd5vzjyv44S/3Oow56fS/DEtBF+83g1I4WXsw13h81rFhiApgku
tffdWuu23ox3ubGtuAVihK1xaOYBqim8dIBoLBN84M6P3H2+NDi4x01/c+4w7wtNCGedGNrjguwQ
0b864BTj0iavTpu0urUicWipsmxCv9p6JlkyVxmUdlgEvP5pPlv43qHopWvUDrYhXP9m45ap4ubg
47Zwpa7QCadghf4vEYUQOcrGcf4oDYa7KUc71VKTY8cAgmdTool8ugYD2ipNV75R5i3Cfbe8Jsyt
q9wy8iuo2Xc3FpUShojyr3JMl7meJupnmT4qGg==
</SignatureValue>
<KeyInfo>
<KeyValue>
<RSAKeyValue>
<Modulus>
xUg5RWGM6yKTu1hctQ0J9VZtr6+7VOQ75lDq7MeqxDTJgkHxO+P49GV/hRjLv3rCXvo9JBM8AKj5
U+/uue5OE6PgeqdS+M7HBF4ieD33wVsRYWuu2TLrw+/DRd6yEs61mPVRLDrIqjxxpa41VUAfwPXV
ksCZ7RNklyfSa5D+Zm6sx3v5kGPylWVpdW+k3BFYmUCW2j1rjGb5X9zV9Egi2VGe2SGsYLNu1aJS
HHAIPc+COJIBMENga/syQSNF2l4/GNUkn84RnlW5P75rPg6Oa+y2UwfUgmgrCeMcyJJKDMy6heqm
6huvgaxOTr9DZqWkxJYW5GGWTUUiq64JB3EjOQ==
</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
</KeyValue>
<X509Data>
<X509Certificate>
MIIElTCCA32gAwIBAgIBLjANBgkqhkiG9w0BAQUFADCBpTEUMBIGA1UEAxMLU0lJLUNBLTIwMTMx
GjAYBgNVBAcTEVNhbnRpYWdvIGRlIENoaWxlMR0wGwYDVQQIExRSZWdpb24gTWV0cm9wb2xpdGFu
YTELMAkGA1UEBhMCQ0wxHDAaBgkqhkiG9w0BCQEWDXNpaS1jYUBzaWkuY2wxJzAlBgNVBAoTHlNl
cnZpY2lvIGRlIEltcHVlc3RvcyBJbnRlcm5vczAeFw0xMzA0MjQxMDM0NDJaFw0xNTA0MjQxMDM0
NDJaMIIBATE6MDgGA1UECxMxRGVwdG8uIGRlIEF0ZW5jaW9uIHkgQXNpc3RlbmNpYSBkZSBDb250
cmlidXllbnRlczEnMCUGA1UEChMeU2VydmljaW8gZGUgSW1wdWVzdG9zIEludGVybm9zMQswCQYD
VQQGEwJDTDEdMBsGA1UECBMUUmVnaW9uIE1ldHJvcG9saXRhbmExGjAYBgNVBAcTEVNhbnRpYWdv
IGRlIENoaWxlMSYwJAYJKoZIhvcNAQkBFhdTSUlfZHRlX2ltcHJlc29zQHNpaS5jbDEqMCgGA1UE
AxMhQ2VydGlmaWNhY2lvbiAgQ0NNICBEZXNhcnJvbGxhZG9yMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAxUg5RWGM6yKTu1hctQ0J9VZtr6+7VOQ75lDq7MeqxDTJgkHxO+P49GV/hRjL
v3rCXvo9JBM8AKj5U+/uue5OE6PgeqdS+M7HBF4ieD33wVsRYWuu2TLrw+/DRd6yEs61mPVRLDrI
qjxxpa41VUAfwPXVksCZ7RNklyfSa5D+Zm6sx3v5kGPylWVpdW+k3BFYmUCW2j1rjGb5X9zV9Egi
2VGe2SGsYLNu1aJSHHAIPc+COJIBMENga/syQSNF2l4/GNUkn84RnlW5P75rPg6Oa+y2UwfUgmgr
CeMcyJJKDMy6heqm6huvgaxOTr9DZqWkxJYW5GGWTUUiq64JB3EjOQIDAQABo3EwbzAJBgNVHRME
AjAAMD0GA1UdEQQ2MDSgGAYIKwYBBAHBAQGgDBMKNDUwMDAwNTItM6AYBggrBgEEAcEBA6AMEwo2
MDgwMzAwMC1LMCMGA1UdEgQcMBqgGAYIKwYBBAHBAQKgDBMKNjA4MDMwMDAtSzANBgkqhkiG9w0B
AQUFAAOCAQEAWbf4jOaJgvx4676oKqHoHlO5/y/8umb2eCjddVKWxrytL4Ncx/6aJSgmMBj52Whe
gHJf3+SCarDYgo2L7AzaIL7/nM1KtlKpcpqFU+LC+AFf4MctSe8nthdg7VaKze1f5W2ZKvVBDNwI
1LFrbBEn6w3PlkcJ0AjvlJBEgPlMzQVEKSEGdPOTbsiWvSxdxj8HuFFKx3R+bH9ZkNjP5s06nTFh
SFVVIYZvCQ/qIYyUCBe4ZvH02ekYK8KeO6suiDI8cctoC+DWGfSvcLEt07AuwuVbqzAde32ACnC2
lqqstjt3FuB3nYymxbrnzhJjpPkTt9m9MbSFvJzrAgQ7joO1Dw==
</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>

xmlファイルに基づいてキーを作成するためにこれを作成しましたが、どれを選択するかを選択できません。最初に見つかったものを使用していると思います(ただし、xmlには3つあります)また、使用方法もわかりませんそれを検証します。

RSAKeyValue で x509certificate/2 を作成できません。

XmlElement XmlSignature;
XmlSignature = (XmlElement)fix2.DocumentElement.SelectSingleNode("//Signature");
RSAKeyValue key = new RSAKeyValue();
key.LoadXml(XmlSignature);
4

1 に答える 1

7

これは、解決策を得るのに十分なはずです。以下のコードは、xml ドキュメントの最も外側の Signature 要素の署名を検証します。

内側のものを検証しない理由は、それらが外側の署名ブロックによってラップされているためだと思います。含まれている要素ごとに個別の XmlDocument インスタンスを作成する手順を実行し、それらのノードごとに同じ手順を個別に実行する必要があります。 .

以下のコードでは、3 回目の反復で「passes」が true になります。

ソリューションで実行したいことは、xpath を介して外側の署名ノードを取得し、そのノードのみを検証してから、ドキュメント内のノードごとに新しい XmlDocument インスタンスを作成し、それらのノードごとに個別の証明書検証を行うことです。

        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.PreserveWhitespace = true;
        xmlDoc.Load("ENVIO_DTE_345508.xml");
        SignedXml signedXml = new SignedXml(xmlDoc);
        XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature");
        XmlNodeList certificates = xmlDoc.GetElementsByTagName("X509Certificate");
        X509Certificate2 dcert2 = new X509Certificate2(Convert.FromBase64String(certificates[0].InnerText));
        foreach (XmlElement element in nodeList) {
            signedXml.LoadXml(element);
            bool passes = signedXml.CheckSignature(dcert2, true);
        }
于 2014-12-17T18:28:41.797 に答える