〜 卓越した品質へ 〜

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

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

This site uses Akismet to reduce spam. Learn how your comment data is processed.