2015年5月15日金曜日

XML文書に電子署名をしてみる

いまさらながらXML署名について調べてみた。

感覚的には理解できたけど、実際の処理に興味があったので、特殊なツールを使わずにXML文書に電子署名をしてみる。

目的は、Online XML Digital Signature Veriferで検証可能なXML署名を作成すること。

参照要素の作成

まず、署名対象のXML文書のダイジェスト値を求める。

以下が今回の署名対象となるXML文書(target.xml)。かなり、適当なXML文書である。

<?xml version="1.0" encoding="UTF-8"?>
<sample>
<!-- comment -->
<msg lang ="ja">hello</msg>
</sample>

つぎに、このXML文書を正規化(Canonicalization)する。

正規化の手順は、http://www.w3.org/TR/xmldsig-core/#sec-c14nAlgにある。

参考:Canonical XML

色々と定義があるようだが、ここではXML宣言とコメント、そして改行コード「\n」を削除する。要素属性の余計な空白も取り除く。

こんな感じ。

$ cat target.xml | tr -d '\012' > target_c14n.xml
$ cat target_c14n.xml
<sample><msg lang="ja">hello</msg></sample>
バイナリダンプは以下の通り。
$ hexdump target_c14n.xml
0000000 3c 73 61 6d 70 6c 65 3e 3c 6d 73 67 20 6c 61 6e
0000010 67 3d 22 6a 61 22 3e 68 65 6c 6c 6f 3c 2f 6d 73
0000020 67 3e 3c 2f 73 61 6d 70 6c 65 3e 
正規化できたら、XML文書のダイジェスト値を計算する。
 
$ openssl dgst -sha1 -binary target_c14n.xml | base64
21hWqJrA9IIsNLbKwiMH2xrD4R0=

このダイジェスト値を用いてDigestValue要素を定義して、

<DigestValue>21hWqJrA9IIsNLbKwiMH2xrD4R0=</DigestValue>

この要素を含めた参照(Reference)要素を作成する。

<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>21hWqJrA9IIsNLbKwiMH2xrD4R0=</DigestValue>
</Reference>
<Reference URI="">は署名対象の参照先を意味しており、envelopedタイプ(署名対象XML文書に署名自体も含む)はURI=""とかになる模様。

<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>は作成するXML署名がenvelopedタイプであることを示す。

また、<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>はダイジェスト値をもとめたときのアルゴリズムを示している。

以上で参照要素が完成した。

署名情報要素(SignedInfo)の作成


署名情報要素(SignedInfo)は、先ほどの参照要素(Reference)に加え、CanonicalizationMethod要素、SignatureMethod要素が必要になる。
 
signedinfo.xml

<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></CanonicalizationMethod>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></SignatureMethod>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>
<DigestValue>21hWqJrA9IIsNLbKwiMH2xrD4R0=</DigestValue>
</Reference>
</SignedInfo>

これを正規化する。

$ cat signedinfo.xml | tr -d '\012' > signedinfo_c14n.xml
正規化後は以下のようになる。

signedinfo_c14n.xml


<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#"><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></CanonicalizationMethod><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></SignatureMethod><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></Transform></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod><DigestValue>21hWqJrA9IIsNLbKwiMH2xrD4R0=</DigestValue></Reference></SignedInfo>

改行コードやEOFも削除する。これで署名情報要素ができた。

バイナリダンプは以下のとおり。

$ hexdump signedinfo_c14n.xml
0000000 3c 53 69 67 6e 65 64 49 6e 66 6f 20 78 6d 6c 6e
0000010 73 3d 22 68 74 74 70 3a 2f 2f 77 77 77 2e 77 33
0000020 2e 6f 72 67 2f 32 30 30 30 2f 30 39 2f 78 6d 6c
0000030 64 73 69 67 23 22 3e 3c 43 61 6e 6f 6e 69 63 61
0000040 6c 69 7a 61 74 69 6f 6e 4d 65 74 68 6f 64 20 41
0000050 6c 67 6f 72 69 74 68 6d 3d 22 68 74 74 70 3a 2f
0000060 2f 77 77 77 2e 77 33 2e 6f 72 67 2f 32 30 30 31
0000070 2f 31 30 2f 78 6d 6c 2d 65 78 63 2d 63 31 34 6e
0000080 23 22 3e 3c 2f 43 61 6e 6f 6e 69 63 61 6c 69 7a
0000090 61 74 69 6f 6e 4d 65 74 68 6f 64 3e 3c 53 69 67
00000a0 6e 61 74 75 72 65 4d 65 74 68 6f 64 20 41 6c 67
00000b0 6f 72 69 74 68 6d 3d 22 68 74 74 70 3a 2f 2f 77
00000c0 77 77 2e 77 33 2e 6f 72 67 2f 32 30 30 30 2f 30
00000d0 39 2f 78 6d 6c 64 73 69 67 23 72 73 61 2d 73 68
00000e0 61 31 22 3e 3c 2f 53 69 67 6e 61 74 75 72 65 4d
00000f0 65 74 68 6f 64 3e 3c 52 65 66 65 72 65 6e 63 65
0000100 20 55 52 49 3d 22 22 3e 3c 54 72 61 6e 73 66 6f
0000110 72 6d 73 3e 3c 54 72 61 6e 73 66 6f 72 6d 20 41
0000120 6c 67 6f 72 69 74 68 6d 3d 22 68 74 74 70 3a 2f
0000130 2f 77 77 77 2e 77 33 2e 6f 72 67 2f 32 30 30 30
0000140 2f 30 39 2f 78 6d 6c 64 73 69 67 23 65 6e 76 65
0000150 6c 6f 70 65 64 2d 73 69 67 6e 61 74 75 72 65 22
0000160 3e 3c 2f 54 72 61 6e 73 66 6f 72 6d 3e 3c 2f 54
0000170 72 61 6e 73 66 6f 72 6d 73 3e 3c 44 69 67 65 73
0000180 74 4d 65 74 68 6f 64 20 41 6c 67 6f 72 69 74 68
0000190 6d 3d 22 68 74 74 70 3a 2f 2f 77 77 77 2e 77 33
00001a0 2e 6f 72 67 2f 32 30 30 30 2f 30 39 2f 78 6d 6c
00001b0 64 73 69 67 23 73 68 61 31 22 3e 3c 2f 44 69 67
00001c0 65 73 74 4d 65 74 68 6f 64 3e 3c 44 69 67 65 73
00001d0 74 56 61 6c 75 65 3e 32 31 68 57 71 4a 72 41 39
00001e0 49 49 73 4e 4c 62 4b 77 69 4d 48 32 78 72 44 34
00001f0 52 30 3d 3c 2f 44 69 67 65 73 74 56 61 6c 75 65
0000200 3e 3c 2f 52 65 66 65 72 65 6e 63 65 3e 3c 2f 53
0000210 69 67 6e 65 64 49 6e 66 6f 3e                
000021a

署名準備

XML署名に用いる秘密鍵、証明書を作成する。

まず、2048ビット長のRSA秘密鍵を作成する

$ openssl genrsa -out private-key.pem 2048
秘密鍵の内容を確認する。※秘密鍵は絶対に公開してはならない。意味がなくなるから。今回はあくまで練習のため。
 
$ openssl rsa -in private-key.pem
writing RSA key
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAmlg5wx9jWcdPYB54zH+kIsZ5geFalcawV4cOg1M6n11fDikt
aViTTY3yPtzjJGVc+coqoARenRqg27NkYj32ofxc0e9k9+dlK0BXl/toBmRenSuR
xvyO3iVTtN1z3AHZDMpmhj2obs72KzFg+XnNJ47MYBQx3oL6o30wcSNmj/J2vUr1
Jnex2Z5dn189eXadEsxYKLGmwsO5Ocs0yyYj6ua8i+/CWmLA2fzVdid0tfe+ArTx
VLqA6jOBdrUMcJw5Dn5VLYObyUndVga47k3++fy299hARvX8CODGhddQeDuhb0iz
9tiQiImrTRIUyke7Vp1yHCHKzf6E2W2fKLKH/QIDAQABAoIBADPkSbdSjEKZAhTc
6dxHZdXTSPLj42LL5GnpHHYGu4TtDZJjQcNTZmMCwFlmRm/sLHBHCkG2dmD3nPGA
xNVK4+reQA7NH/NBNwBtp4WPnw/XGwBYr7BpJVeG0TfT5KopbOIiAopLnJ90scsf
1OzLiLAuEISVBZc8Dix9YJYJQuhOJPEB4cqFmvag+W71PrmVozpFKWjMhWHtL2Dn
VEfWEtlv0QyKQdHTtcONnGGvRFTkA5z5iziQ/mh7skP5Ks92VoZTeQlHZTGcEPIr
9G1/8PUCRAFCZSSn7yVHdzv8MedAKSx4KZk9gvgbYTyOW93sHQH06zl4RQZX0/U+
VAix5HkCgYEAyucZBC8vOsEbboXMTtZ9LAXdfNyZEt8ev7Nw22B78aeGxWw2F/sn
PJKKqdgRsm7hbyOeydZQ/mqBQE3Ri6kp1I4qvpQ+aK6XjGIjYYymZgaWE6/uQAJU
U8fS4TtG7t0BuCfgQ8fsS95g9mg6zMyV+4OM2oqaUWPh6NU0toUInisCgYEAwrwd
IpJlVNGX6oXlZz/RlL5LjVCgxD1m0wU3vGRXHePjFcTmjgub0Jjr6Kg+WnocdcIk
rM1YWYPgsjvhN3ucnTD+/Y1kKzcfr3ovtrp8F8QrZTiMxTAZ0S7sJlxYxuD7fgKu
YVeHKZMybV8qC7wS5EJM4LyXx+DLphyv9Zf0BncCgYAM+BqMPuvY6JD1To4Rl/om
PzW6DmumXiacAD89dnxVpOyjX9hRThdi8sb0NkBjVF0Keo9ivVUt/ebHEnJLaAOp
d3DZ/6XBkS9UpM04JgJY0SD0nzEuXDfBpysehGhzSiMa/0mBa5z5+HvgJCdmAcmw
aucs7OESRL0i4cXdyMEVQwKBgAoqQacVVz7HNhPi62epWCpYiJ8Wz12PCvgG9LLb
1gRUaf0v6w0NJBQOd3oMljyo1SV8feebTHpXvPnw0D/SLwmxjg30PH9ZAElrqmPy
dhnTfqRpAEgmy6I0vdT+yw+OnPIl965TIFYWPfKhnhNAvQe3QkYU8iNX46mHI9RB
G1bfAoGAEaSnaFbUJTDipC2aJldGx+iNAtKu/QTZLS6FPjSewRdMGNBvhxVfygpc
EBtwbGpSXyysyg3vdDZjWygjLFHnWS1gy+YLZ9A56Ha+cGvazPQ1ZAEes0tjmL6V
gT/EgCkYcBseVUFROhfkTi/jbvD+kS8tuPB8G1plbfWJ1HCXZRQ=
-----END RSA PRIVATE KEY-----
秘密鍵から公開鍵を作成する。(今回は使わないけど)

$ openssl rsa -pubout -in private-key.pem -out public-key.pem

公開鍵の中身を確認する。
   
$ openssl rsa -pubin -in public-key.pem
writing RSA key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmlg5wx9jWcdPYB54zH+k
IsZ5geFalcawV4cOg1M6n11fDiktaViTTY3yPtzjJGVc+coqoARenRqg27NkYj32
ofxc0e9k9+dlK0BXl/toBmRenSuRxvyO3iVTtN1z3AHZDMpmhj2obs72KzFg+XnN
J47MYBQx3oL6o30wcSNmj/J2vUr1Jnex2Z5dn189eXadEsxYKLGmwsO5Ocs0yyYj
6ua8i+/CWmLA2fzVdid0tfe+ArTxVLqA6jOBdrUMcJw5Dn5VLYObyUndVga47k3+
+fy299hARvX8CODGhddQeDuhb0iz9tiQiImrTRIUyke7Vp1yHCHKzf6E2W2fKLKH
/QIDAQAB
-----END PUBLIC KEY-----
証明書署名要求(CSR, Certificate Signing Request)を作成する。  
     
$ openssl req -new -key private-key.pem -out csr.pem -subj '/C=JP/ST=Tokyo/L=Hino/O=Sheepcloud org./OU=Dept/CN=sheepcloud.org'

つぎに、
Online XML Digital Signature Veriferから認証局証明書と秘密鍵(passphraseは"secret")をダウンロードしてくる。検証を成功させるために必要。

$ curl -O https://www.aleksey.com/xmlsec/tests/keys-certs/cacert.pem
$ curl -O https://www.aleksey.com/xmlsec/tests/keys-certs/cakey.pem

Online XML Digital Signature Veriferの認証局証明書でCSRを署名する。

$ openssl x509 -req -in csr.pem -days 3650 -CA cacert.pem -CAkey cakey.pem -set_serial 123 -out cert.pem
Signature ok
subject=/C=JP/ST=Tokyo/L=Hino/O=Sheepcloud org./OU=Dept/CN=sheepcloud.org
Getting CA Private Key
Enter pass phrase for cakey.pem:secret

署名

 作成した秘密鍵で署名情報要素(SignedInfo)に署名し、Base64でエンコードする。

$ openssl dgst -sha1 -sign private-key.pem signedinfo_c14n.xml|base64
FknPmWmHFeI2gSX1FoNokRDr9W26NbOhY6xFxT3AJwi9Rp4uzCzA/ptU+nG5oQOHMFc439NMuZgnf69ttCbPAdjbLoBwbddydFQNKZwDq2BH2h0cKjQcRr++95vF9H9esZ92UlSVK2JPm4xA43NAzvm0APvarkGRM1ZwBKXP+LFeoERV1ZyHQ+eIloyeJBA2lyNtYl0qID9Tbdnk9JH26z7Qq9M3wKc6PzzaYUclAezG61yISRccD0G7WIHOnLyrOSD+QC3+g4W7bffxR1+2FKQmt00qG6zjik5ofVfHTv1ugpKXcLc2p+AesSXpj8EB9yw7xaSOypUr/WAKsJmw1w==
 
エンコード結果をSignatureValue要素の値にする。  
 
<SignatureValue>FknPmWmHFeI2gSX1FoNokRDr9W26NbOhY6xFxT3AJwi9Rp4uzCzA/ptU+nG5oQOHMFc439NMuZgnf69ttCbPAdjbLoBwbddydFQNKZwDq2BH2h0cKjQcRr++95vF9H9esZ92UlSVK2JPm4xA43NAzvm0APvarkGRM1ZwBKXP+LFeoERV1ZyHQ+eIloyeJBA2lyNtYl0qID9Tbdnk9JH26z7Qq9M3wKc6PzzaYUclAezG61yISRccD0G7WIHOnLyrOSD+QC3+g4W7bffxR1+2FKQmt00qG6zjik5ofVfHTv1ugpKXcLc2p+AesSXpj8EB9yw7xaSOypUr/WAKsJmw1w==</SignatureValue>

署名のバイナリダンプは次のとおり。

$ openssl dgst -sha1 -sign private-key.pem signedinfo_c14n.xml|hexdump
0000000 16 49 cf 99 69 87 15 e2 36 81 25 f5 16 83 68 91
0000010 10 eb f5 6d ba 35 b3 a1 63 ac 45 c5 3d c0 27 08
0000020 bd 46 9e 2e cc 2c c0 fe 9b 54 fa 71 b9 a1 03 87
0000030 30 57 38 df d3 4c b9 98 27 7f af 6d b4 26 cf 01
0000040 d8 db 2e 80 70 6d d7 72 74 54 0d 29 9c 03 ab 60
0000050 47 da 1d 1c 2a 34 1c 46 bf be f7 9b c5 f4 7f 5e
0000060 b1 9f 76 52 54 95 2b 62 4f 9b 8c 40 e3 73 40 ce
0000070 f9 b4 00 fb da ae 41 91 33 56 70 04 a5 cf f8 b1
0000080 5e a0 44 55 d5 9c 87 43 e7 88 96 8c 9e 24 10 36
0000090 97 23 6d 62 5d 2a 20 3f 53 6d d9 e4 f4 91 f6 eb
00000a0 3e d0 ab d3 37 c0 a7 3a 3f 3c da 61 47 25 01 ec
00000b0 c6 eb 5c 88 49 17 1c 0f 41 bb 58 81 ce 9c bc ab
00000c0 39 20 fe 40 2d fe 83 85 bb 6d f7 f1 47 5f b6 14
00000d0 a4 26 b7 4d 2a 1b ac e3 8a 4e 68 7d 57 c7 4e fd
00000e0 6e 82 92 97 70 b7 36 a7 e0 1e b1 25 e9 8f c1 01
00000f0 f7 2c 3b c5 a4 8e ca 95 2b fd 60 0a b0 99 b0 d7
0000100

証明書からSubject DNを取得し、X509SubjectName要素を定義する。
 
$ openssl x509 -in cert.pem -text | grep Subject:
Subject: C=JP, ST=Tokyo, L=Hino, O=Sheepcloud org., OU=Dept, CN=sheepcloud.org
取得し、
<X509SubjectName>C=JP, ST=Tokyo, L=Hino, O=Sheepcloud org., OU=Dept, CN=sheepcloud.org</X509SubjectName>
定義する。

証明書をX509Certificate要素に設定する。

$ openssl x509 -in cert.pem
-----BEGIN CERTIFICATE-----
MIIDHjCCAocCAXswDQYJKoZIhvcNAQELBQAwgbwxCzAJBgNVBAYTAlVTMRMwEQYD
VQQIEwpDYWxpZm9ybmlhMT0wOwYDVQQKEzRYTUwgU2VjdXJpdHkgTGlicmFyeSAo
aHR0cDovL3d3dy5hbGVrc2V5LmNvbS94bWxzZWMpMR4wHAYDVQQLExVUZXN0IFJv
b3QgQ2VydGlmaWNhdGUxFjAUBgNVBAMTDUFsZWtzZXkgU2FuaW4xITAfBgkqhkiG
9w0BCQEWEnhtbHNlY0BhbGVrc2V5LmNvbTAeFw0xNTA1MTMxNTEyMzBaFw0yNTA1
MTAxNTEyMzBaMG4xCzAJBgNVBAYTAkpQMQ4wDAYDVQQIDAVUb2t5bzENMAsGA1UE
BwwESGlubzEYMBYGA1UECgwPU2hlZXBjbG91ZCBvcmcuMQ0wCwYDVQQLDAREZXB0
MRcwFQYDVQQDDA5zaGVlcGNsb3VkLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAJpYOcMfY1nHT2AeeMx/pCLGeYHhWpXGsFeHDoNTOp9dXw4pLWlY
k02N8j7c4yRlXPnKKqAEXp0aoNuzZGI99qH8XNHvZPfnZStAV5f7aAZkXp0rkcb8
jt4lU7Tdc9wB2QzKZoY9qG7O9isxYPl5zSeOzGAUMd6C+qN9MHEjZo/ydr1K9SZ3
sdmeXZ9fPXl2nRLMWCixpsLDuTnLNMsmI+rmvIvvwlpiwNn81XYndLX3vgK08VS6
gOozgXa1DHCcOQ5+VS2Dm8lJ3VYGuO5N/vn8tvfYQEb1/AjgxoXXUHg7oW9Is/bY
kIiJq00SFMpHu1adchwhys3+hNltnyiyh/0CAwEAATANBgkqhkiG9w0BAQsFAAOB
gQBrX5gnLIEZFdI7A5ywZpaw5M5PdUR1pKEnKA9ARkPWkNcGC/Is1Qn1DpUHpIE7
by6zOulby6Grn8j9zfj9XG8ujyzIqtzNJkdyWXROa1BBOxkLu1XnyXYU7LVNi7x3
5BGZT5SK6MclYIzuoAfTACiume5Jr88GeV/QcsPdWTJ+GQ==
-----END CERTIFICATE-----
あとはこれらの情報を以下のXML署名雛形に埋めていく。

<?xml version="1.0" encoding="UTF-8"?><sample><msg lang="ja">hello</msg><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><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></DigestValue></Reference></SignedInfo><SignatureValue></SignatureValue><KeyInfo><X509Data><X509SubjectName></X509SubjectName><X509Certificate></X509Certificate></X509Data></KeyInfo></Signature></sample>
完成したXML署名は以下のとおり。
<?xml version="1.0" encoding="UTF-8"?><sample><msg lang="ja">hello</msg><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><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>21hWqJrA9IIsNLbKwiMH2xrD4R0=</DigestValue></Reference></SignedInfo><SignatureValue>FknPmWmHFeI2gSX1FoNokRDr9W26NbOhY6xFxT3AJwi9Rp4uzCzA/ptU+nG5oQOHMFc439NMuZgnf69ttCbPAdjbLoBwbddydFQNKZwDq2BH2h0cKjQcRr++95vF9H9esZ92UlSVK2JPm4xA43NAzvm0APvarkGRM1ZwBKXP+LFeoERV1ZyHQ+eIloyeJBA2lyNtYl0qID9Tbdnk9JH26z7Qq9M3wKc6PzzaYUclAezG61yISRccD0G7WIHOnLyrOSD+QC3+g4W7bffxR1+2FKQmt00qG6zjik5ofVfHTv1ugpKXcLc2p+AesSXpj8EB9yw7xaSOypUr/WAKsJmw1w==</SignatureValue><KeyInfo><X509Data><X509SubjectName>CN=test,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU</X509SubjectName><X509Certificate>MIIDhjCCAu+gAwIBAgIBATANBgkqhkiG9w0BAQsFADCBvDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
CkNhbGlmb3JuaWExPTA7BgNVBAoTNFhNTCBTZWN1cml0eSBMaWJyYXJ5IChodHRwOi8vd3d3LmFs
ZWtzZXkuY29tL3htbHNlYykxHjAcBgNVBAsTFVRlc3QgUm9vdCBDZXJ0aWZpY2F0ZTEWMBQGA1UE
AxMNQWxla3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tMB4XDTE1
MDUxMzA4MzEyMloXDTE2MDUxMjA4MzEyMlowVDELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUt
U3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDENMAsGA1UEAwwEdGVzdDCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJpYOcMfY1nHT2AeeMx/pCLGeYHhWpXGsFeH
DoNTOp9dXw4pLWlYk02N8j7c4yRlXPnKKqAEXp0aoNuzZGI99qH8XNHvZPfnZStAV5f7aAZkXp0r
kcb8jt4lU7Tdc9wB2QzKZoY9qG7O9isxYPl5zSeOzGAUMd6C+qN9MHEjZo/ydr1K9SZ3sdmeXZ9f
PXl2nRLMWCixpsLDuTnLNMsmI+rmvIvvwlpiwNn81XYndLX3vgK08VS6gOozgXa1DHCcOQ5+VS2D
m8lJ3VYGuO5N/vn8tvfYQEb1/AjgxoXXUHg7oW9Is/bYkIiJq00SFMpHu1adchwhys3+hNltnyiy
h/0CAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQg
Q2VydGlmaWNhdGUwHQYDVR0OBBYEFMx99EfHBvUhCn6Q+ByacE1jkXVQMB8GA1UdIwQYMBaAFNpG
6Wvmr9M9quUhS1LtymYo4P6FMA0GCSqGSIb3DQEBCwUAA4GBAEdZ6Bidq3ZGURdRkCiU+rKYpQx/
HkW/ibIbrIZowaAIcqC8AkmLB4nrPX+DODU6huiwzPrTk4JyHwEnHhtJRJh3cknAwVTDz6slbEpa
eT7Biv5klcoOAljRF3NZKwVJGqDZMEPdK0ofGhp6i5JlZ7dwzXir57+JVGxwhyRikl/u</X509Certificate></X509Data></KeyInfo></Signature></sample>

検証

Online XML Digital Signature Veriferで検証する。

無事、検証終了。

RESULT: Signature is OK
---------------------------------------------------
= VERIFICATION CONTEXT
== Status: succeeded
== flags: 0x00000000
== flags2: 0x00000000
== Key Info Read Ctx:
= KEY INFO READ CONTEXT
== flags: 0x00000000
== flags2: 0x00000000
== enabled key data: all
== RetrievalMethod level (cur/max): 0/1
== TRANSFORMS CTX (status=0)
== flags: 0x00000000
== flags2: 0x00000000
== enabled transforms: all
=== uri: NULL
=== uri xpointer expr: NULL
== EncryptedKey level (cur/max): 0/1
=== KeyReq:
==== keyId: rsa
==== keyType: 0x00000001
==== keyUsage: 0x00000002
==== keyBitsSize: 0
=== list size: 0
== Key Info Write Ctx:
= KEY INFO WRITE CONTEXT
== flags: 0x00000000
== flags2: 0x00000000
== enabled key data: all
== RetrievalMethod level (cur/max): 0/1
== TRANSFORMS CTX (status=0)
== flags: 0x00000000
== flags2: 0x00000000
== enabled transforms: all
=== uri: NULL
=== uri xpointer expr: NULL
== EncryptedKey level (cur/max): 0/1
=== KeyReq:
==== keyId: NULL
==== keyType: 0x00000001
==== keyUsage: 0xffffffff
==== keyBitsSize: 0
=== list size: 0
== Signature Transform Ctx:
== TRANSFORMS CTX (status=2)
== flags: 0x00000000
== flags2: 0x00000000
== enabled transforms: all
=== uri: NULL
=== uri xpointer expr: NULL
=== Transform: exc-c14n (href=http://www.w3.org/2001/10/xml-exc-c14n#)
=== Transform: rsa-sha1 (href=http://www.w3.org/2000/09/xmldsig#rsa-sha1)
=== Transform: membuf-transform (href=NULL)
== Signature Method:
=== Transform: rsa-sha1 (href=http://www.w3.org/2000/09/xmldsig#rsa-sha1)
== Signature Key:
== KEY
=== method: RSAKeyValue
=== key type: Private
=== key usage: -1
=== key not valid before: 1431505882
=== key not valid after: 1463041882
=== rsa key: size = 2048
=== list size: 1
=== X509 Data:
==== Key Certificate:
==== Subject Name: /C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=test
==== Issuer Name: /C=US/ST=California/O=XML Security Library (http://www.aleksey.com/xmlsec)/OU=Test Root Certificate/CN=Aleksey Sanin/emailAddress=xmlsec@aleksey.com
==== Issuer Serial: 1
==== Certificate:
==== Subject Name: /C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=test
==== Issuer Name: /C=US/ST=California/O=XML Security Library (http://www.aleksey.com/xmlsec)/OU=Test Root Certificate/CN=Aleksey Sanin/emailAddress=xmlsec@aleksey.com
==== Issuer Serial: 1
== SignedInfo References List:
=== list size: 1
= REFERENCE VERIFICATION CONTEXT
== Status: succeeded
== URI: ""
== Reference Transform Ctx:
== TRANSFORMS CTX (status=2)
== flags: 0x00000000
== flags2: 0x00000000
== enabled transforms: all
=== uri: NULL
=== uri xpointer expr: NULL
=== Transform: enveloped-signature (href=http://www.w3.org/2000/09/xmldsig#enveloped-signature)
=== Transform: c14n (href=http://www.w3.org/TR/2001/REC-xml-c14n-20010315)
=== Transform: sha1 (href=http://www.w3.org/2000/09/xmldsig#sha1)
=== Transform: membuf-transform (href=NULL)
== Digest Method:
=== Transform: sha1 (href=http://www.w3.org/2000/09/xmldsig#sha1)
== Manifest References List:
=== list size: 0
ポイントはダイジェスト値、署名を行う対象となるXML文書の正規化。

署名前、署名後のXML文書からは改行やEOFを削除する。
 

参考文献


  • http://www.w3.org/TR/xmldsig-core/
    • 仕様。拾い読みしただけ。ちゃんと読まないと。 
  • https://www.aleksey.com/xmlsec/xmldsig-verifier.html
    • XMLSec Cライブラリのサイト。ここのOnline Validatorにはお世話になった。
  • http://www.atmarkit.co.jp/ait/articles/0207/24/news001.html
    • 日本語。わかりやすい。 
  • http://www.di-mgt.com.au/xmldsig.html
    •  一番お世話になったサイト。SignedInfo要素へ署名する際、改行コードやEOFがあるといけないようなのだが、このサイトのバイナリダンプをみるまでそれがわからなかった。
  • http://www.w3.org/TR/xml-c14n11/
    • XML正規化仕様。ちゃんと読んでいない。