2.署名されたXML文書を検証する
.NET Frameworkには、XML文書を容易に扱えるクラスが用意されています。さらに、そのXML文書に暗号化や電子署名を施すクラスもあります。ここでは電子署名されたXML文書を、.NET Frameworkのクラスを使って検証する方法を説明します。
.NET Framework XML署名・検証は、W3C 勧告『XML-Signature Syntax and Processing』に準拠しています。
.NET Framework XML署名・検証は、W3C 勧告『XML-Signature Syntax and Processing』に準拠しています。
2.1 概要
署名されたXML文書を.NET Frameworkによって検証方法をC#言語で説明します。
関連の名前空間は以下のとおりです。
なお、署名された文書1.XML文書に電子証明書で署名するで電子署名された文書です。見やすくするためにインデントや改行が入っていますので、このままのデータを検証すると失敗します。(signed.xmlとして利用するものです。)
関連の名前空間は以下のとおりです。
- System.XmlXML文書を扱うためのAPIを備えています。
- System.Security.cryptographyデータの安全なエンコーディングやデコーディング、およびハッシュ演算、乱数生成、メッセージ認証などの操作を含む、暗号サービスが提供されます。
- System.Security.cryptography.XmlXML デジタル署名の作成と検証をサポートするクラスを含んでいます。この名前空間のクラスは、W3C 勧告『XML-Signature Syntax and Processing』(http://www.w3.org/TR/xmldsig-core/)が実装されています。
- System.Security.cryptography.X509Certificates共通言語ランタイムにおける Authenticode X.509 v.3 証明書の実装が格納されています。この証明書は、証明書の所有者を一意に、そして確実に識別する秘密キーで署名されているものです。
- 署名されたXML文書をロードする。
- SignedXMLクラスを準備し署名検証に備える。
- キーProviderを準備する。
- 署名部分を取り出し検証する。
なお、署名された文書1.XML文書に電子証明書で署名するで電子署名された文書です。見やすくするためにインデントや改行が入っていますので、このままのデータを検証すると失敗します。(signed.xmlとして利用するものです。)
<root> <creditcard> <number>19834209</number> <expiry>02/02/2002</expiry> </creditcard>> <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=""> <Transforms> <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /> </Transforms> <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /> <DigestValue>qf9G+NGDr9YbsV4Tu1a8je/DCLE=</DigestValue> </Reference> </SignedInfo> <SignatureValue>Qysxl+4tHKgczZKEJash5TtlHAJjuZ+DScSDz6wCf2KtR3v QELKhlMa22YXh0HOi6q3/5HJi5WpKAif3rPZXMTet/3ESMJn/8xL0LG zEod2kL0XRw2ubT9uoqVqeUcxJ4WBNQNg0+9z8zYno3Jks2QvimGZav E7UHgLrL9Q47vI=</SignatureValue> <KeyInfo> <X509Data> <X509Certificate>MIIEvjCCA6agAwIBAgIQKjHnW8ti/1AlJgCYYX YRBTANBgkqhkiG9w0BAQUFADCB3TELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduL CBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJt cyBvZiB1c2UgYXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNTEeMBwGA1U ECxMVUGVyc29uYSBOb3QgVmFsaWRhdGVkMTcwNQYDVQQDEy5WZXJpU2lnbiBDbGFzcyAxIE luZGl2aWR1YWwgU3Vic2NyaWJlciBDQSAtIEcyMB4XDTEwMDgwOTAwMDAwMFoXDTEwMTAwO DIzNTk1OVowggELMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNp Z24gVHJ1c3QgTmV0d29yazFGMEQGA1UECxM9d3d3LnZlcmlzaWduLmNvbS9yZXBvc2l0b3J 5L1JQQSBJbmNvcnAuIGJ5IFJlZi4sTElBQi5MVEQoYyk5ODEeMBwGA1UECxMVUGVyc29uYS BOb3QgVmFsaWRhdGVkMScwJQYDVQQLEx5EaWdpdGFsIElEIENsYXNzIDEgLSBNaWNyb3NvZ nQxFzAVBgNVBAMUDkhpcm9zaGkgVGFrYWt1MSUwIwYJKoZIhvcNAQkBFhZ0YWtha3UyMDEx QHlhaG9vLmNvLmpwMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2X3fYZmb+CTNP7CC n81cTHtD6fd5VECsDJH3OOdXmnoEzXsocxfoPeEG30gbjnPPul8ruypAd19dEIfbFhpoCDr kmGEn3p4Mz9BCqmLzMSUn6FikyclBk4byrQ3wwfOY2VDGkvjXQnQtwHPKn5laUqHKyTBfqT iRuUbgsJpuPNQIDAQABo4HMMIHJMAkGA1UdEwQCMAAwRAYDVR0gBD0wOzA5BgtghkgBhvhF AQcXATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMAsGA1U dDwQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDBAYIKwYBBQUHAwIwSgYDVR0fBEMwQTA/oD 2gO4Y5aHR0cDovL0luZEMxRGlnaXRhbElELWNybC52ZXJpc2lnbi5jb20vSW5kQzFEaWdpd GFsSUQuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQBhaHBfyQWHuR4gH4lyRTsNbyj1CKPvrQwM vPo0IinZiwPy5WMqHp7/mzVfopS/FnPVllWTPuuS5BgZwFw11O3BbKRZEzYGGfCq94WLkTl NgpeO7ngUuq+DWFcHDkezGvTLtNhTrzoCQZz53DpMjvVoFWYGdNHD0fc/W0/ez9C8k3vQ19 p9x9zEmhm29vzxKBoMXnZAauD42/BXjsxCvIzMmeJJjiMZRN3sUkI1oR8L41jfCINvrTgEJ bz79hX69oxw2Xv1Pt5O4/5mY7NIZ0DH3V39RL9R4/yAQAv527dZ5z8Wc6X7GRSkbXME+c+T Hav353zQ8tg/cJyA+YuKtkbm</X509Certificate> </X509Data> </KeyInfo> </Signature> </root>
2.2 署名されたXML文書をロードする
まず、署名されたXML文書をロードします。
以下にコードを記します。
以下にコードを記します。
using System; using System.Xml; using System.Security.Cryptography; using System.Security.Cryptography.Xml; namespace dsig { class dsig { static void Main(string[] args) { // XMLドキュメントを生成する XmlDocument doc = new XmlDocument(); // XmlDocumentのフォーマットを指定し、 // オブジェクトにXMLデータを読み込む doc.PreserveWhitespace = true; doc.Load("signed.xml");
2.3 SignedXMLクラスを準備する
署名された文書を使って署名検証するオブジェクトを生成します。
以下に、コードを記します。
以下に、コードを記します。
// SignedXmlオブジェクト生成 SignedXml signedXml = new SignedXml(doc);
2.4 キーProviderを準備する
署名を検証するキーProviderを準備します。今回はあらかじめRSAキーであることがわかっていますのでそのProviderを準備します。
以下にコードを記します。
以下にコードを記します。
// キーProviderを準備 RSACryptoServiceProvider Key = new RSACryptoServiceProvider();
2.5 "Signature" ノードを取り出す
署名された文書から、"Signature"ノードを取り出します。ここでは、Enveloped署名が1つのみ含まれていることがわかっていますのでそのとおりに処理します。
以下にコードを記します。
以下にコードを記します。
// キーProviderを準備 // "Signature"ノードを探し出し、新たなXmlNodeListオブジェクト // とする XmlNodeList nodeList = doc.GetElementsByTagName("Signature"); // ノードが見つからない場合は、例外をスローする if(nodeList.Count <= 0) { throw new CryptographicException("No Signature"); } // 署名が2つ以上の場合は、例外をスローする if(nodeList.Count >= 2) { throw new CryptographicException("More that one signature"); } // "Signature" ノードをロードする signedXml.LoadXml((XmlElement)nodeList[0]);
2.6 署名を検証する
取り出した"Signature"ノードを検証します。
以下にコードを記します。
以下にコードを記します。
// 署名検証 if(signedXml.CheckSignature()) Console.WriteLine("OK"); else Console.WriteLine("NG"); } } }
2.7 注意
ここで説明したコードでは、電子証明書のキーがRSAであることを前提としています。また、署名に使われた電子証明書は検証していませんのでご注意ください。
サンプルコードはお問い合わせください。
(記載の会社名および製品名は、各社の登録商標および商標です。)