電子署名 (overview)

説明

電子署名とは

電子署名とは、インターネットなどの信頼できない経路から送られてきたデータが、正当なものであることを証明するための機構です。

  1. まず、署名する人が秘密鍵を使用して、送信データから固定長の電子署名を作成します。
    (実際には、送信データのハッシュ値を取り、それに対して操作を行います。)
  2. その後、検証する人が、送信データとそのデータへの電子署名をインターネットなどを経由して受け取ります。
  3. 検証する人は、あらかじめ入手していた公開鍵の情報だけを用いて、 送信データとその署名から、データが正当なものであることを検証できます。

電子署名という機構の特徴は以下のようになります。

CRYPTO ライブラリが提供する電子署名機能

TwlSDKのCRYPTOライブラリでは、Nitro-Cryptoの時から存在する電子署名検証機能の他に 電子署名作成機能も追加しました。

電子署名検証機能としては CRYPTO_VerifySignature 関数および CRYPTO_VerifySignatureWithHash 関数で提供しています。 証明書の有効期限管理などの機能はありません。 必要に応じてアプリケーション側で実装して下さい。

電子署名作成機能としては CRYPTO_RSA_Sign 関数を提供しています。 この関数は単独で実行しても処理できません。 この関数を実行する前に CRYPTO_RSA_SignInit 関数で初期化を行い、署名作成実行後に CRYPTO_RSA_SignTerminate 関数で終了処理を行う必要があります。

また、電子署名はデータの正当性の検証を行うだけの仕組みですので、データの暗号化は行いません。
CRYPTOライブラリでは、暗号強度に劣るものの処理が高速なRC4・より暗号強度が高い共通鍵暗号方式のAES・鍵配送の点で有利な公開鍵暗号のRSAという3つの暗号化方式を用意してあります。 RC4 アルゴリズムに関しては RC4 アルゴリズム概要 を、RSA アルゴリズムに関しては RSA アルゴリズム概要 を参照してください。
また、TwlSDKではハードウェア機能を用いたAES暗号化機能も用意しています。詳しくはAESの項目をご覧下さい。

署名データの形式

CRYPTO_VerifySignature* 関数に渡す署名データは以下の条件を満たしていれば どのような方法で生成しても構いません。 (もちろん CRYPTO_RSA_Sign で作成した署名データも利用できます)

署名データの作成例

一例として、オープンソースの SSL ツールキットである OpenSSL で電子署名を作成する手順を以下に述べます。

1. 署名用の RSA 鍵を生成する

OpenSSL がインストールされている環境のコマンドラインで、以下のコマンドを入力することで、 鍵長 1024 bit の RSA 鍵ファイル privkey.pem を作成します。

 > openssl genrsa -out privkey.pem 1024

万が一、privkey.pem が漏洩すると、誰もが署名できるようになってしまいます。 秘密鍵の鍵ファイルは厳重に取り扱うようにしてください。

鍵の作成時に暗号化方式を指定することで、privkey.pem にパスワードによる暗号化を行うことも可能です。 以下の例では、新規に作成した privkey.pem を 3DES アルゴリズムによって暗号化します。

 > openssl genrsa -des3 -out privkey.pem 1024

詳細は openssl のリファレンスを参照してください。

2. RSA 鍵の内容を確認する

以下のコマンドで、privkey.pem の内容を確認することができます。

 > openssl rsa -in privkey.pem -text -noout

この中には、署名を行うために必要な秘密情報が含まれていますが、 後の検証のために必要な情報(公開鍵)は modulus と publicExponent の2つの数値です。
以下はコマンドの出力から modulus と publicExponent を抜粋した例です。


modulus:
00:eb:95:be:33:19:73:64:f2:72:2c:87:c8:0a:f3:
1c:ba:e0:4c:e0:3e:1d:f6:e2:09:aa:70:f0:b3:b9:
0c:86:36:62:2d:12:13:86:fa:a5:3d:93:cb:5f:0b:
45:64:9b:7b:eb:b5:c6:f9:42:99:70:46:f3:14:6d:
8f:f9:b9:ec:38:30:a0:1c:28:0d:30:d9:86:1a:4d:
1b:f2:e9:05:1b:43:06:b2:c0:55:ed:c4:bb:8e:1a:
a5:ab:2b:54:e5:dc:8d:70:cf:af:91:94:c9:e9:8f:
7f:9f:29:28:be:e7:01:b0:20:d4:f2:71:58:93:db:
25:1c:26:bc:98:f3:a2:b3:47
publicExponent: 65537 (0x10001)

CRYPTO_VerifySignature* 関数で扱う公開指数は 65537 で固定ですので、 publicExponent が 65537 であることを確認してください。

modulus の数値は、以下のコマンドで出力することも可能です。

 > openssl rsa -in privkey.pem -modulus -noout

このコマンドでは以下のような文字列が出力されます。

 Modulus=EB95BE33197364F2722C87C80AF31CBAE04CE03E1DF6E209AA70F0B3B90C8636622D121386FAA53D93CB5F0B45649B7BEBB5C6F942997046F3146D8FF9B9EC3830A01C280D30D9861A4D1BF2E9051B4306B2C055EDC4BB8E1AA5AB2B54E5DC8D70CFAF9194C9E98F7F9F2928BEE701B020D4F2715893DB251C26BC98F3A2B347

この出力中の "Modulus=" の後に続く16進数を何らかの方法で C 言語の u8 の配列に変換して、CRYPTO_VerifySignature* 関数に mod_ptr として渡してください。 なお、この出力例では Modulus が 127 バイトですが、このように 128 バイトより少ない場合は 先頭(上位桁)の 0 が省略されていますので、 全体が 128 バイトになるように先頭へ 0 を詰めた状態で mod_ptr に渡す必要があります。

3. 電子署名を作成する

ここまで準備ができれば、あとは任意のデータを持って来て電子署名を作成するだけです。
電子署名は CRYPTO_RSA_Sign を用いるとDS上で作成できますし、PCにて作成することもできます。
以下のコマンドで、秘密鍵 privkey.pem で hoge.txt を署名した hoge.sign という署名データが作成されます。

 > openssl dgst -sha1 -sign privkey.pem -out hoge.sign hoge.txt

出来上がったファイルサイズが 128 バイトであることを確認してください。
この 128 バイトのバイナリデータを DS に転送し、sign_ptr として CRYPTO_VerifySignature* 関数に渡します。
なお、作成した署名データが正しい電子署名となっているかを PC 上で確認するには、以下のコマンドを実行します。

 > openssl dgst -sha1 -prverify privkey.pem -signature hoge.sign hoge.txt

4. 電子署名を検証する

DS のプログラムに予め公開鍵データを埋め込んでおき、そこへ、通信などの何らかの手段でデータ本体とその電子署名データを送ります。 CRYPTO_VerifySignature* 関数に対して、そのデータ本体とサイズ、電子署名データ(128バイト)と、 埋め込まれた公開鍵データ(128バイトのmodulus)を与えることにより、電子署名を検証し、正当なものと認められれば関数は TRUE を返します。

参照

CRYPTO関数一覧

履歴

2008/04/18 電子署名作成機能追加に対応
2008/03/27 TwlSDK移植版 初版
2006/03/07 初版 (NitroCrypto)