LoginSignup
7
6

More than 5 years have passed since last update.

HPKIカードで署名してみる

Last updated at Posted at 2019-01-26

はじめに

HPKIカードというカードがありまして、マイナンバーカードと似たようなものですが、それのお医者さん向けのものです。
手元にこのカードのサンプルがあったので中身を見てみたいと思います。
以前投稿した「マイナンバーカード検証」の続きみたいなものです。
- マイナンバーカード検証#1
- マイナンバーカード検証#2
- マイナンバーカード検証#3

注意事項

  • 日本医師会のサンプルカードを使いますが、専用のHPKIカードドライバを使うものではありません。
  • HPKIカードのPINを何度か間違えるとロックがかかって使えなくなる(はず)です。
  • ロックを解除する方法はここでは記載していないのでご注意ください。
  • HPKIカードはいろんな種類があるみたいです。ここで書いてあることが全ての種類のHPKIカードで使えるかどうかはわかりません。

参考資料

目次

1.環境
2.ファイル構造
3.おやくそく
4.いろいろやってみる
4-1.証明書を取り出して公開鍵を取得
4-2.PINのリトライ回数を調べる
4-3.署名
4-4.Verify
5.ファイル構造を知る方法

1.環境

検証ツール
- OpenSSL
- Git Hub - Lib/DemoApp

2.ファイル構造

HPKIカードのファイル構造はこの図のようになっており、認証用と署名用がある、という点ではJPKIと同じですが、APが二つに分かれている、という点で異なっています。
- 電子認証用AP
- 電子署名用AP
名前の通り解釈して、自分自身の認証に使うのが認証用AP、電子署名するときに使うのが署名用APということだと思います。
それで、両方にPrivate Keyがあるんで、どっちでも署名できる、PINはそれぞれ別に持っている、ということになります。

HPKCardDataModel.png

3.おやくそく

基本的なことはJPKIカードと同じです。
- 証明書を取り出すためにPINは不要。
- Private KeyアクセスにはPINによるアンロックが必要。
- Private Keyにデータを投げつけて署名をGETすることができる。
- PINのリトライ回数は15回、PIN認証を間違えると減っていき、0になると・・・やってないのでどうなるかわかりません。
- PINのアンロックに成功するとリトライ回数は15に戻る。

4.いろいろやってみる

認証用APでいろいろやってみます。
(署名用APもAPの識別子が違うだけで同じです)

C#でICカードにアクセスする方法とか、APDUとは何ぞやという場合はこちらを参照⇒マイナンバーカード検証#1

4-1.証明書を取り出して公開鍵を取得

(1)APをSELECT

APDU = 0x00 A4 04 00 [10] [E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02] 00
※[10]がデータサイズ(0x10⇒16byte)、[E8 28~]がAPの識別子。

(2)認証用証明書をSELECT

APDU = 00 A4 02 0C [02] [00 16]
※[02]がデータサイズ(0x02⇒2byte)、[00 16]がFILEの識別子。

(3)証明書をReadする

(2)でSELECTしたFILEのブロックから証明書をREADします。
証明書データはDER形式で格納されています。
バイナリデータの読み出し方法はこちらを参照⇒(3)READ BINARY

証明書から公開鍵を取り出す

ここもJPKIと同じです。
2.認証用証明書から公開鍵を取り出す

取り出した公開鍵(バイナリデータ)はVerifyに使うので、ファイルにでも保存しておきます。

※DER形式の証明書を拡張子DERでファイル保存するとWindowsではダブルクリックで中身を見ることができます。見てみると「サブジェクトディレクトリ属性」にMedical Doctorと表示されます。
これで、ドクターです、と判断するのかもしれません。

4-2.PINのリトライ回数を調べる

これから署名をやっていきますが、PINをつかうので、まずはPINのリトライ回数をチェックできるようにしておきます。PINを間違えすぎると大変なことになります。

(1)APをSELECT

さっきと一緒

(2)PINをSELECT

APDU = 00 A4 02 0C [02] [00 02]

(3)VERIFY PINコマンド

  • APDU = 0x00, 0x20, 0x00, 0x88
  • Response = 0x63, 0xCE

Responseで0x63, 0xC?といった値が返ってきます。このとき?にロックまでのリトライ回数が返ってきます。このコマンドでリトライ回数が減ることはありませんので安心してください。

4-3.署名

やっと署名をするところにきましたが、まず、HPKIカードで『署名』する機能とは一体何なのか、を説明したいと思います。


電子署名(でんししょめい)とは、電磁的記録(電子文書)に付与する、電子的な徴証であり、紙文書における印章やサイン(署名)に相当する役割をはたすものである
wikipediaより


例えば とあるPDFファイルの署名を得るには、PDFファイルをバイナリでReadしてHPKIカードに丸ごと送り付けるのか、というと、そうではありません。

HPKIカードで署名をするには認証用鍵FILEにSELECTして、APDUコマンドである形式のデータを送信します。そうすると、バイナリデータが返ってきます。それが署名です。
APDUで送信するある形式のデータは署名対象のファイルのことではなく署名対象のファイルのDigest Infoです。Digest InfoとはPKCS #1 (RFC 3447) で決められている電子署名の形式です。

つまり、送信側が署名対象のファイルから Digest Info 形式のデータを作成して、そのデータをHPKIカードに送信するということです。

具体的な方法はこちらを参照してください ⇒ 電子署名について

OpenSSLのコマンドでいうと(メモ)
openssl rsautl -sign -inkey hpkiprivatekey.pem -in digest_info_of_targetfile.dat
↑HPKIカードでやっていること

openssl dgst -sha1 -sign hpkiprivatekey.pem targetfile.dat
↑PKCS #1 (RFC 3447)の電子署名をOpenSSLで作成するコマンド

4-4.Verify

署名検証方法はJPKIと同じです。
4.検証

5.ファイル構造を知る方法

HPKIカードはこのようなファイル構造をしていますが、マルチベンダーを想定していて、ある程度自由にファイル構造を定義できるような仕様となっています。ベンダー毎に構造が違っていては実装する側は大変ですので、ファイル構造の定義そのものをカードに格納する仕様になっています。
その仕様がJIS X 6320-15 (ISO/IEC 7816-15)で、HPKIカードはこの仕様に基づいてファイル構造をEF.ODというファイルに持っています。
EF.ODを読み出してカード内のファイル構造を知ることができます。

image.png

これは情報が少なくて、JISの資料をみてもわざとわからなくしているような書き方なんで全く理解できないのですが、こちらのサイトでわかりやすく書いてあります。
Rubyを使ってHPKIカードのデータを読み取る

おつかれさまでした

HPKIカードはJPKIカードとほぼ一緒なんで、あまり書くことがなかったなぁ

参考

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6