OpenSSLから発行した証明書を利用して,暗号/復号処理を実行しました。今度は,署名/検定処理を実行してみます。
概要
RSAで署名を実行すると,署名値はRSA鍵長(1024bitや2048bit)となります。通常はPKCS#7の形式にして,署名値だけではなく署名に利用した証明書やルート証明書なども一緒に相手に送ります。署名を受け取った相手は,署名検定を実行します。
サンプルソース
署名/検定のサンプルは次の通り。
署名は38行目で実行しています。1行で完了。検定はverify_p7で実施しています。ルート証明書をストアに追加して,ストアに証明書チェーンを構築しています。中間証明書もある場合は,ストアに中間証明書も追加する必要があります。
# OpenSSLの動作を確認するサンプル require 'openssl' # util class # バイナリと16進文字列の変換 class String def hex2bin s = self raise "Not a valid hex string" unless(s = ~ /^[\da-fA-F]+$/) s = '0' + s if((s.length & 1) != 0) s.scan(/../).map{ |b| b.to_i(16) }.pack('C*') end def bin2hex self.unpack('C*').map{ |b| "%02x" % b }.join('') end end # PKCS#12ファイルをデコードする def decode_pkcs12(p12_file, pw = '1111') # PKCS#12ファイルを開く f = File.new(p12_file) p12 = OpenSSL::PKCS12.new(f, pw) f.close # 証明書、鍵ペアを取り出す cert = p12.certificate # ユーザ証明書を取得 ca_cert = p12.ca_certs # CA証明書を取得 priv_key = p12.key # 秘密鍵を取得 pub_key = priv_key.public_key # 公開鍵を取得 return priv_key, pub_key, cert, ca_cert end # 署名を実行する(PKCS#7生成) def sign_data(priv_key, cert, data, ca_cert) # PKCS#7のオブジェクトを生成し署名を実行する signed_data = OpenSSL::PKCS7.sign(cert, priv_key, data, ca_cert, OpenSSL::PKCS7::BINARY) return signed_data end # 署名検定を実行する def verify_p7(p7data, data, ca_cert) # 証明書チェーンができるように証明書ストアを作成する store = OpenSSL::X509::Store.new store.add_cert(ca_cert[0]) # CA証明書を追加 p7 = OpenSSL::PKCS7.new(p7data) # PKCS#7オブジェクトを生成 # PKCS#7データを検定 verified = p7.verify(nil, store, data, OpenSSL::PKCS7::DETACHED || OpenSSL::PKCS7::NOVERIFY) if !verified then puts p7.error_string # 検定結果を表示 end return verified end # 呼び出し text = "Sign Verify test" puts 'OpenSSLで署名/検定処理を実行する。' puts '署名対象文 : ' puts text priv_key, pub_key, cert, ca_cert = decode_pkcs12('user2.p12', '1111') signed_data = sign_data(priv_key, cert, text, ca_cert) puts '署名結果 : ' puts signed_data.to_s # PEM形式で表示 puts '' verify = verify_p7(signed_data, text, ca_cert) puts '検定結果' puts verify puts ''
実行結果
実行結果を見ると,署名/検定が成功していることが分かります。PKCS#7データにはユーザ証明書やルート証明書が格納されているのでサイズが大きくなっています。
OpenSSLで署名/検定処理を実行する。 署名対象文 : Sign Verify test 署名結果 : -----BEGIN PKCS7----- MIIK0gYJKoZIhvcNAQcCoIIKwzCCCr8CAQExCzAJBgUrDgMCGgUAMB8GCSqGSIb3 DQEHAaASBBBTaWduIFZlcmlmeSB0ZXN0oIIH+TCCBBEwggL5oAMCAQICCQDDsKzL mZvY3DANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9r eW8xFzAVBgNVBAoMDlRydXN0ZWQgRGVzaWduMQ0wCwYDVQQLDARteUNBMQ0wCwYD VQQDDARteUNBMScwJQYJKoZIhvcNAQkBFhhhZG1pbkB0cnVzdGVkLWRlc2lnbi5u ZXQwHhcNMTYwNDAzMjA0NTMzWhcNMTcwNDAzMjA0NTMzWjCBlTELMAkGA1UEBhMC SlAxDjAMBgNVBAgMBVRva3lvMRAwDgYDVQQHDAdFZG9nYXdhMRcwFQYDVQQKDA5U cnVzdGVkIERlc2lnbjESMBAGA1UECwwJQ2VydFVzZXJzMQ4wDAYDVQQDDAV1c2Vy MjEnMCUGCSqGSIb3DQEJARYYdXNlcjJAdHJ1c3RlZC1kZXNpZ24ubmV0MIIBIjAN BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1NPtRN6RxoQgB5dq1hSpQv0ExVJ7 sQDcfLQ8wRCpEDSS106RCIzW5N4dAQBQWbjIb3C0TOti9JyX31GYJNikbNf0htNZ 2WQlgbCw/c5Csv2xpt/gqMXRj7e9pCPAGbocA0gDn2Cl5fXk8z1DJiuCqFbpWbDj v+26OavlRAtbtrQkrasqhOLCJfIXjNviCw8qHQ8nPus00hOygWEBuXivR0u0pOhW 1SG7bnwq01X9YuU67zRFWVDi1Ow+qsiYGsyzbpZ2nbGrbwEHS8PN0q+Nj9eQxCao +uIqk2yBw0U2edRbuS+jCh5sRI+4IY+0KxBTVXukaGv4+CMn2CLkB4EarwIDAQAB o3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRl ZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUfCZVTDLz5AGTI7FoRQn7KOMe2ZYwHwYD VR0jBBgwFoAU0Flll5CM2qLsX3mUTK9elPvBsiMwDQYJKoZIhvcNAQELBQADggEB ADmcgW6IiteeIGFbmQc5uPeUl1n8tasdLKERhA2im4/GymWBY7cPVJyoggqgTBkf 6XWAJf6scyY//lZTfGajPW8PX8mde5eYsN7IMx/3GNDK73la8rDgiLwwX9viXxJV +MUz38dYFFjiYn2pHYnvZ63LpG7E2ConQaFEqtFaOL3hDDEiECyIb+/mDRxvEo+a EWGjukR55E3vb3z+Z9Jej7zloivEX3xt6wbbs4I5KP8taMqPbp44tWsnABuudjp9 A1yiv+WHTkI3frjqyG1Jb1tXBS3xmJnoQZqgTWPpqHur72xW/uAzb7Sz5V+h/XC+ qza9VVOmjIxl+4I8i8um7fIwggPgMIICyKADAgECAgkAw7Csy5mb2NowDQYJKoZI hvcNAQELBQAwfTELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRva3lvMRcwFQYDVQQK DA5UcnVzdGVkIERlc2lnbjENMAsGA1UECwwEbXlDQTENMAsGA1UEAwwEbXlDQTEn MCUGCSqGSIb3DQEJARYYYWRtaW5AdHJ1c3RlZC1kZXNpZ24ubmV0MB4XDTE2MDMx OTAwNDgyM1oXDTE5MDMxOTAwNDgyM1owfTELMAkGA1UEBhMCSlAxDjAMBgNVBAgM BVRva3lvMRcwFQYDVQQKDA5UcnVzdGVkIERlc2lnbjENMAsGA1UECwwEbXlDQTEN MAsGA1UEAwwEbXlDQTEnMCUGCSqGSIb3DQEJARYYYWRtaW5AdHJ1c3RlZC1kZXNp Z24ubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq9y39ocqHKnh 8w81Zt6cYC91krdSTZAg+ILRlBBfoz3uSG4/tu2SH/V3FtteshXMqu3EEZTG5iyJ 5e2F+/N4YKlaSuP3Y2nleJxCFvcTlsajyh+KLWppu5PYEXVtK4+VhYXGIJ8/VeW/ mqs3YKc5Vvoddo+e2Lbe6HCSwyorxVbd7UUEsnBS4o4WRhFGdHyYZ+e+KFKvRO4C nq6jgaoPskELVKUdO2+rD0tiD18fKB3rsEwpb3dv6Sw6qsCqY6HTc+MMb7Ux7XTM SKZ05OUb4wBvgkrDc4PLtHiFjicz/lJl5HMYp9qT+QGya5Fn1bGy0AIu/sDjsfmM QcS8eFCmkQIDAQABo2MwYTAdBgNVHQ4EFgQU0Flll5CM2qLsX3mUTK9elPvBsiMw HwYDVR0jBBgwFoAU0Flll5CM2qLsX3mUTK9elPvBsiMwDAYDVR0TBAUwAwEB/zAR BglghkgBhvhCAQEEBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAC/8hlwiKrrJ3gfh Db4SKm+JzkC3qJrAfYbJ/HL3PNkt7R1nKf5l/Xy2L2MG4U/i9DEoNhgqAcBdrRfC h99+/0z/VO5a4vDU0V6iz32nnfjnOiXOx+6aCVeoYo6W7nhxGpiS4QBZhKsp70ci epBs8+H5UxYohIYte1vbaAHGexvNy0aPBTn8sd4fWMz8QL853D3J2sczPv6q5VF2 WnRuL6M0hhWfI0CznbmseVFxx1LfUdVZnGk+SMNflK82JHAxqeAK1e0iuTcyRP40 SZ3wzT4HlhBTDxoXWv11IH3Tk+IuAPqBsJSdsn+Ie+j+MRxA4dVsn29ihFKhlmjU oaZkvbUxggKNMIICiQIBATCBijB9MQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9r eW8xFzAVBgNVBAoMDlRydXN0ZWQgRGVzaWduMQ0wCwYDVQQLDARteUNBMQ0wCwYD VQQDDARteUNBMScwJQYJKoZIhvcNAQkBFhhhZG1pbkB0cnVzdGVkLWRlc2lnbi5u ZXQCCQDDsKzLmZvY3DAJBgUrDgMCGgUAoIHYMBgGCSqGSIb3DQEJAzELBgkqhkiG 9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTE2MDQwNTIzMjkxMVowIwYJKoZIhvcNAQkE MRYEFPE8t+v/T/LyIT3mu8MpQ6YOJU1QMHkGCSqGSIb3DQEJDzFsMGowCwYJYIZI AWUDBAEqMAsGCWCGSAFlAwQBFjALBglghkgBZQMEAQIwCgYIKoZIhvcNAwcwDgYI KoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsOAwIHMA0GCCqGSIb3DQMC AgEoMA0GCSqGSIb3DQEBAQUABIIBAHimZ8p/ZeHaysHaEyxzPr3pQyVqsoo/ehs5 oQ6RKiky91XttXqIireYSHMHSTQLzIVfwmqAT5jks95cRHQ8ieMTIjm3dmGT3nSF jqB5Rqz5/tJkg3aJRnlU28MUyIQiwsN6AHfRvhoxH0YGUF97zdtymamo8drZj9nK GwX1RPFjFkb7Luw/nbplNP7KaFfY4UPJFL39GnAPdqFxeaOAXj+IlL6EdNZTxPbG DVtUTrU8zcBGZeEZPR1daX42P1E8BCa05BigwA0lUH4CLJMAmt7mRsy/p4vsbnLu 7xzkuHGR3+LgMr0pqIvfdI/OsXncbi7s5mayf2bQ3WGJVLrN2So= -----END PKCS7----- 検定結果 true