|
USBトークンとは? 形はUSBフラッシュメモリに似ていますが、内部にCPUやEEPROMを搭載した特殊なデバイスで、別の形として、接触型・非接触型ICカード(スマートカード)などがあります。トークン内部でキーペアの生成などの暗号処理ができ、格納された秘密鍵を使用するためには、PINや生体認証を使用します。PINの入力に失敗した場合、ロックさせる機能や、デバイスを破壊して、情報を盗むようなことをすると、自動的に秘密情報を消去するような仕組み(耐タンパ性)を持つことが特徴です。これらを、「(暗号処理機能付き)ハードウェア・トークン」や「セキュリティ・トークン」と呼びます。
認証システムの要素として、
Something You Know・・・その人しか知り得ない知識(パスワード・PIN) Something You Have・・・その人しか持ち得ない物(社員証・住民基本台帳カードなど) Something You Are ・・・その人自身の情報(指紋・掌紋など生体認証情報など) がありますが、上記2つの要素を組み合わせることで、よりセキュアになります。このことを二要素認証 (Two-Factor Authentication)といい、ハードウェア・トークンはこれを実現することができます。 今回、ハードウェア・トークンであるAladdin eToken PRO を使って、実験を行いました。 Debian Linux にOpenSCをインストールする LinuxでICカードやUSBトークンにX.509 ディジタル証明書やRSA 秘密鍵などの暗号クレデンシャルを格納するには、オープンソースのミドルウェアOpenSC が使用できます。 購入したスマートカードリーダやUSBトークンに、Linux用のドライバが付属していない場合があると思います。 OpenCT (スマートカードリーダ用ドライバ類)は、eTokenなど、メジャーなスマートカードリーダやUSBトークンに対応しています。
まず、トークン内でRSAキーペアを生成し、自己署名証明書を格納してみます。 準備 debian etchでは以下のコマンドでインストールできます。
# apt-get install opensc openct pcscd
あと、libopenct1 libusb libopensc2 も必要かもしれません。opensslコマンドをUSBトークン上で行うため、openssl と libopensc-openssl もインストールしておきます。 <セキュリティ情報> OpenSCに脆弱性 JPSERT 2008月27日号 OpenSC 0.11.5 より前のバージョンをお使いの方は、修正済みのバージョンに更新して下さい。
eTokenをUSBポートに挿すと、赤く点灯します。
#lsusb Bus 005 Device 001: ID 0000:0000 Bus 003 Device 001: ID 0000:0000 Bus 002 Device 002: ID 0529:0600 Aladdin Knowledge Systems Bus 002 Device 001: ID 0000:0000 Bus 004 Device 001: ID 0000:0000 Bus 001 Device 001: ID 0000:0000 デバイスがきちんと認識されているようです。 # opensc-tool --list-readers Readers known about: Nr. Driver Name 0 openct Aladdin eToken PRO 64k 1 openct OpenCT reader (detached) 2 openct OpenCT reader (detached) 3 openct OpenCT reader (detached) 4 openct OpenCT reader (detached)
今回リーダ番号は0で認識されています。0以外のときは、各コマンドでリーダ番号を指定する必要があります。 例) # opensc-tool --reader 1 --name CardOS M4
キーペアの生成からディジタル証明書の格納まで トークン管理ユーザをscardグループに追加します。以降、rootでなくても作業可能です。 # adduser <hoge> scard
- トークンの中身を消去する (ブランクカードの場合は省略)
$ pkcs15-init --erase-card PIN [Security Officer PIN] required. Please enter PIN [Security Officer PIN]: PIN [Security Officer PIN] required. Please enter PIN [Security Officer PIN]:
ここでエラーになってしまう場合は、付属のトークン管理ツール (Aladdin eTokenでは、Windows版 eToken RTE 3.65) でイニシャライズし,ブランクカードの状態にします。(トークン内に格納されている証明書など、すべて削除されてしまうので注意してください)
$ pkcs15-init --create-pkcs15 New Security Officer PIN (Optional - press return for no PIN). Please enter Security Officer PIN: Please type again to verify: Unblock Code for New User PIN (Optional - press return for no PIN). Please enter User unblocking PIN (PUK): Please type again to verify:
これで、USBトークン内にPKCS#15用のディレクトリが作成され、RSAキーペアやディジタル証明書を格納するための領域が確保されました。
$ pkcs15-init --store-pin --auth-id 01 --label "Test User" New User PIN. Please enter User PIN: Please type again to verify: Unblock Code for New User PIN (Optional - press return for no PIN). Please enter User unblocking PIN (PUK): Please type again to verify: Security officer PIN required. Please enter Security officer PIN: ユーザPINは8文字以内で設定して下さい。(eTokenの場合) また、auth-id 01 は必須です。
$ pkcs15-init --generate-key rsa/1024 --auth-id 01 Security officer PIN required. Please enter Security officer PIN: User PIN required. Please enter User PIN: Security officer PIN required. Please enter Security officer PIN: eToken 64k は、RSA/2048bitキーに対応していますが、ここでは、1024bitで生成しています。 $ pkcs15-tool --list-keys
Private RSA Key [Private Key] Com. Flags : 3 Usage : [0x4], sign Access Flags: [0x1D], sensitive, alwaysSensitive, neverExtract, local ModLength : 1024 Key ref : 16 Native : yes Path : 3f005015 Auth ID : 01 ID : 45 USBトークン内にRSA秘密鍵、RSA公開鍵がキーID:45として、格納されました。
$openssl OpenSSL> engine dynamic -pre SO_PATH:/usr/lib/engines/engine_pkcs11.so \ -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD \ -pre MODULE_PATH:opensc-pkcs11.so (dynamic) Dynamic engine loading support [Success]: SO_PATH:/usr/lib/engines/engine_pkcs11.so [Success]: ID:pkcs11 [Success]: LIST_ADD:1 [Success]: LOAD Loaded: (pkcs11) pkcs11 engine OpenSSL>
Opensslからpkcs#11を通してUSBトークンを操作できるようになりました。(openssl.confを編集しておく方法もあります。)
OpenSSL> req -engine pkcs11 -new -key id_45 -keyform engine -out req.pem -text -x509 engine "pkcs11" set. PKCS#11 token PIN: You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:JP State or Province Name (full name) [Some-State]:kanagawa Locality Name (eg, city) []:sagamihara Organization Name (eg, company) [Internet Widgits Pty Ltd]:clustcom Organizational Unit Name (eg, section) []: Common Name (eg, YOUR name) []:Test User Email Address []:
このメールアドレスは、スパムロボットから保護されています。アドレスを確認するにはJavaScriptを有効にしてください
OpenSSL> OpenSSL> q カレントディレクトリに証明書要求ファイル(req.pem)が保存されました。このファイルをベリサインなどのCAに送って署名をしてもらうこともできます。
$ pkcs15-init --store-certificate req.pem --auth-id 01 --id 45 --format pem
User PIN required. Please enter User PIN: Security officer PIN required. Please enter Security officer PIN: ここで、auth-id と (キー)id 45 は、キーの生成時の値と一致させる必要があります。
$pkcs15-tool --dump PKCS#15 Card [OpenSC Card]: Version : 1 Serial number : 2556CE140420 Manufacturer ID: OpenSC Project Last update : 20081127174631Z Flags : EID compliant PIN [Security Officer PIN] Com. Flags: 0x3 ID : ff Flags : [0xBA], local, unblock-disabled, initialized, needs-padding, soPin Length : min_len:6, max_len:8, stored_len:8 Pad char : 0x00 Reference : 1 Type : ascii-numeric Path : 3f005015 PIN [Test User] Com. Flags: 0x3 ID : 01 Flags : [0x3A], local, unblock-disabled, initialized, needs-padding Length : min_len:4, max_len:8, stored_len:8 Pad char : 0x00 Reference : 3 Type : ascii-numeric Path : 3f005015 Private RSA Key [Private Key] Com. Flags : 3 Usage : [0x4], sign Access Flags: [0x1D], sensitive, alwaysSensitive, neverExtract, local ModLength : 1024 Key ref : 16 Native : yes Path : 3f005015 Auth ID : 01 ID : 45 Public RSA Key [Public Key] Com. Flags : 2 Usage : [0x4], sign Access Flags: [0x0] ModLength : 1024 Key ref : 0 Native : no Path : 3f0050153048 Auth ID : ID : 45
X.509 Certificate [Certificate] Flags : 2 Authority: no Path : 3f0050153149 ID : 45 以上で、ひととおりの作業が完了しました。
$pkcs11-tool --login --test Please enter User PIN: ユーザPINを入力すると、テスト結果が表示されます。得にエラーがでていなければ、問題ないでしょう。
PKCS12形式ファイルのインポート 前回の実験で作成した pkcs#12形式ファイルをインポートしてみます。 $ pkcs15-init --store-private-key newcert.p12 --format pkcs12 --auth-id 01 error:23076071:PKCS12 routines:PKCS12_parse:mac verify failure Please enter passphrase to unlock secret key: Importing 1 certificates: 0: /C=JP/O=clustcom/CN=User8 Security officer PIN required. Please enter Security officer PIN: User PIN required. Please enter User PIN: Security officer PIN required. Please enter Security officer PIN: インポートできましたがエラーが表示されています。 $ pkcs15-init --store-private-key newscert.p12 --format pkcs12 --passphrase XXXXX --auth-id 01 Importing 1 certificates: 0: /C=JP/O=clustcom/CN=User8 Security officer PIN required. Please enter Security officer PIN: User PIN required. Please enter User PIN: Security officer PIN required. Please enter Security officer PIN: このように、--passphrase XXXXXを指定すると、エラー表示はなくなりました。
クライアントから接続してみる Firefoxの「ツール」→「オプション」→「暗号化」→「セキュリティデバイス」を選択。(Debian のiceweaselの場合は、「編集」→「設定」→「詳細」→「暗号化」 「セキュリティデバイス」の「追加」でPKCS#11モジュールを選択します。Debianの場合は、/usr/lib/opensc/opensc-pkcs11.soを指定し、Windowsの場合は、OpenSCのWindows版 scb-0.10.exe をインストールし、C:\Program Files\Smart card bundle\opensc-pkcs11.dllを指定します。(windows用のトークンドライバも必要です。) PINを入力すると、トークン内にアクセスできます。 サーバに接続すると、証明書の選択画面が表示されますので、使用する証明書を選択すると、クライアント認証で接続することができました。以下の図は Wireshark というスニファでパケットをキャプチャーしたものです。(注意! 自管理下以外のネットワークで実験しないて下さい) パケットの説明 クライアント(192.168.20.1)、 サーバ(192.168.20.150)
No19からNo27まで、証明書の交換や暗号方式の選択と、データの暗号化に使用する共通鍵の生成と受け渡しが行われています。 No28から暗号化したデータの通信が行われています。
もしも証明書になんらかの問題がある場合は、 Alert Message がサーバから通知されます。 正当なクライアント証明書を持っていない場合は、接続することはできません。

まとめ このように、USBトークンから秘密鍵は一切外にでることはなく、サーバとセキュアに通信することができます。また、秘密鍵にアクセスするためには、PINの入力が必要であり、トークン内で秘密鍵の生成~署名処理までが行われるため、セキュリティレベルが向上します。 物理的な実体であるUSBトークンは、所有者が紛失・盗難に気づく可能性が高く、即座に証明書を失効させれば、危険にさらされる時間は短時間で済みます。
参考 電子認証に関するガイドライン OpenSCOnDebian
|