マイナンバーカード検証#3 - 署名用電子証明書&Library JPKI Reader

#はじめに
マイナンバーカードの検証の話です。
[#2](https://qiita.com/gebo/items/fa35c1f725f4c443f3f3)からの続きです。

#目次
[１．署名用電子証明書](#%EF%BC%91%E7%BD%B2%E5%90%8D%E7%94%A8%E9%9B%BB%E5%AD%90%E8%A8%BC%E6%98%8E%E6%9B%B8)
[１－１．署名用証明書の取得](https://qiita.com/gebo/items/37fcb50565c5ebeacb7b#%EF%BC%91%EF%BC%91%E7%BD%B2%E5%90%8D%E7%94%A8%E8%A8%BC%E6%98%8E%E6%9B%B8%E3%81%AE%E5%8F%96%E5%BE%97)
[１－２．署名用証明書から公開鍵を取り出す](#%EF%BC%91%EF%BC%92%E7%BD%B2%E5%90%8D%E7%94%A8%E8%A8%BC%E6%98%8E%E6%9B%B8%E3%81%8B%E3%82%89%E5%85%AC%E9%96%8B%E9%8D%B5%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99)
[１－３．署名](#%EF%BC%91%EF%BC%93%E7%BD%B2%E5%90%8D)
[１－４．検証](#%EF%BC%91%EF%BC%94%E6%A4%9C%E8%A8%BC)

[２．Library JPKI Reader](#%EF%BC%92library-jpki-reader)
[２－１．とりあえず動かしてみる](#%EF%BC%92%EF%BC%91%E3%81%A8%E3%82%8A%E3%81%82%E3%81%88%E3%81%9A%E5%8B%95%E3%81%8B%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B)
[２－２．ライブラリ解説](#%EF%BC%92%EF%BC%92%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E8%A7%A3%E8%AA%AC)

３．署名用証明書の中の個人情報について


![image.png](https://qiita-image-store.s3.amazonaws.com/0/252291/6110fd4a-167b-d6e3-6fbd-1cd8551c89c5.png)


#１．署名用電子証明書
[#2]()の認証用証明書のときとほぼ同じですが、
- APDUでSELECT FILEする際のファイル識別子(00-1Aなどの2byte)が違う
- 署名用証明書にアクセスするためにPINが必要
- 署名用のPINは認証用のPINとは違うので注意

ここからは極力端折っています。

####１－１．署名用証明書の取得
- SELECT FILE 公的個人認証AP　⇒　[#2と同じ](https://qiita.com/gebo/items/fa35c1f725f4c443f3f3#%EF%BC%91select-file-%E5%85%AC%E7%9A%84%E5%80%8B%E4%BA%BA%E8%AA%8D%E8%A8%BCap)
- SELECT FILE **[署名用]**PIN
	- APDU = `0x00, 0xA4, 0x02, 0x0C, 0x02, [0x00, 0x1B]`
- VERIFY 署名用PIN　⇒　[#2と同じ](https://qiita.com/gebo/items/fa35c1f725f4c443f3f3#%EF%BC%93verify-%E8%AA%8D%E8%A8%BC%E7%94%A8pin)
- SELECT FILE **[署名用]**証明書
	- APDU = `0x00, 0xA4, 0x02, 0x0C, 0x02, [0x00, 0x01]`
- READ BINARY　⇒　[#2と同じ](https://qiita.com/gebo/items/fa35c1f725f4c443f3f3#%EF%BC%93read-binary)

####１－２．署名用証明書から公開鍵を取り出す
[#2と同じです](https://qiita.com/gebo/items/fa35c1f725f4c443f3f3#%EF%BC%92%E8%AA%8D%E8%A8%BC%E7%94%A8%E8%A8%BC%E6%98%8E%E6%9B%B8%E3%81%8B%E3%82%89%E5%85%AC%E9%96%8B%E9%8D%B5%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99)

####１－３．署名
- SELECT FILE 公的個人認証AP　⇒　[#2と同じ](https://qiita.com/gebo/items/fa35c1f725f4c443f3f3#%EF%BC%91select-file-%E5%85%AC%E7%9A%84%E5%80%8B%E4%BA%BA%E8%AA%8D%E8%A8%BCap)
- SELECT FILE **[署名用]**PIN
	- APDU = `0x00, 0xA4, 0x02, 0x0C, 0x02, [0x00, 0x1B]`
- VERIFY 署名用PIN　⇒　[#2と同じ](https://qiita.com/gebo/items/fa35c1f725f4c443f3f3#%EF%BC%93verify-%E8%AA%8D%E8%A8%BC%E7%94%A8pin)
- SELECT FILE **[署名用]**鍵
	- APDU = `0x00, 0xA4, 0x02, 0x0C, 0x02, [0x00, 0x1A]`
- COMPUTE DIGITAL SIGNATURE　⇒　[#2と同じ](https://qiita.com/gebo/items/fa35c1f725f4c443f3f3#%EF%BC%95compute-digital-signature)

####１－４．検証
[#2と同じです](https://qiita.com/gebo/items/fa35c1f725f4c443f3f3#%EF%BC%94%E6%A4%9C%E8%A8%BC)

#２．Library JPKI Reader
ここまでの内容をDLLにしたので紹介します。

**あんまりテストしていません。**
**PIN周りのところにバグがあってカードがロックされても自己責任でお願いします。**

##２－１．とりあえず動かしてみる
- お手元にマイナンバーカードをご用ください
- Win10パソコンにパソリ-PaSoRi RC-S380を接続してICカードが読めるようにしてください
- [ココ](https://github.com/gebogebogebo/JPKIReader/tree/master/bin)からバイナリ一式をダウンロードします。
- `testUI01.exe` を実行します。
- パソリにICカードを乗せて「Check JPKI」をクリックして「Success」って出たらOKです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/252291/25a2fcf8-f268-01dd-8f4d-d60136f3f946.png)

###機能一覧

|ボタン|説明|
|:-:|:---|
|Get UID|カードのUIDを取得して表示します。マイナンバーカードのUIDはGETする度変わるのであんまり意味はないです。|
|Check JPKI|カードがマイナンバーカードかどうかチェックします|
|Get Auth Certificate|認証用証明書をファイルに保存します。[#2でやったことです。](https://qiita.com/gebo/items/fa35c1f725f4c443f3f3#%EF%BC%91%E8%AA%8D%E8%A8%BC%E7%94%A8%E8%A8%BC%E6%98%8E%E6%9B%B8%E3%81%AE%E5%8F%96%E5%BE%97)|
|Get Auth PublicKey|認証用公開鍵をファイルに保存します。[#2でやったことです。](https://qiita.com/gebo/items/fa35c1f725f4c443f3f3#%EF%BC%92%E8%AA%8D%E8%A8%BC%E7%94%A8%E8%A8%BC%E6%98%8E%E6%9B%B8%E3%81%8B%E3%82%89%E5%85%AC%E9%96%8B%E9%8D%B5%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99)|
|Get Auth CA|認証用CAをファイルに保存します。|
|Get Auth PIN Retry Count|認証用PINのリトライカウントを確認します。[#2でやったことです。](https://qiita.com/gebo/items/fa35c1f725f4c443f3f3#%EF%BC%93verify-%E8%AA%8D%E8%A8%BC%E7%94%A8pin)   |
|Signature using Auth Private Key|認証用鍵で電子署名を作成してファイルに保存します。[#2でやったことです。](https://qiita.com/gebo/items/fa35c1f725f4c443f3f3#%EF%BC%93%E7%BD%B2%E5%90%8D)|
|Get Sig Certificate|署名用証明書をファイルに保存します。#3でやったことです。|
|Get Sig Public Key|署名用公開鍵をファイルに保存します。#3でやったことです。|
|Get Sig CA|署名用CAをファイルに保存します。|
|Get Sig PIN Retry Count|署名用PINのリトライカウントを確認します。|
|Signature using Sig Private Key|署名用鍵で電子署名を作成してファイルに保存します。|
|Verify|署名を検証します。Public Key File、Target File、Signature Fileを指定してから実行してください。[#2でやったことです。](https://qiita.com/gebo/items/fa35c1f725f4c443f3f3#%EF%BC%94%E6%A4%9C%E8%A8%BC)|

##２－２．ライブラリ解説
ソースは以下の場所です。
https://github.com/gebogebogebo/JPKIReader

###ライブラリ構成
- **JPKIReader.dll**(本体)
- NLog.dll(logger)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/252291/3420b345-f350-c22c-a68c-89836aae7b4f.png)

###JPKIReader.dllの使い方

簡単です。

```CS:C#で使うサンプル

// 認証用公開鍵GETする
// 戻り値=DER形式の公開鍵
byte[] authPubKey = JPKIReaderLib.JPKIReader.GetAuthenticationPublicKey();

// ファイルの電子署名を作成する
// 第1引数=PIN
// 第2引数=電子署名する対象のファイル(パス＆ファイル）
// 戻り値=電子署名
byte[] sig = JPKIReaderLib.JPKIReader.SignatureUsingAuthenticationPrivateKey("9999", file);

// 電子署名を検証する
// 第1引数=DER形式の公開鍵
// 第2引数=電子署名
// 第3引数=電子署名する対象のファイル(パス＆ファイル）
// 戻り値=true/false
bool isVerifySuccess = JPKIReaderLib.Verify.VerifySignature(authPubKey , sig , file)

```

詳細は[サンプルプログラム](https://github.com/gebogebogebo/JPKIReader/blob/master/Source/JPKIReader/testUI01/MainWindow.xaml.cs)を参照のこと


#３．署名用証明書の中の個人情報について（追記）
署名用証明書の中には個人情報が含まれています。
**含まれている個人情報は、氏名、生年月日、住所などで、マイナンバーは含まれていません。**
マイナンバーはカード裏側の2次元バーコードをスキャンすると簡単に読み取ることができます。

以下の方法で確認します。

- Get Sig Certificate で署名用証明書をエクスポートする。
- エクスポートされたファイル「Signature_Certificate.der」をダブルクリックすると証明書ビューアが起動する。
- 詳細タブから「サブジェクト代替名」を表示する。
- OhterNameがいくつか並んでいるのHEXデータと思われる部分が個人情報(UTF-8 HEX 表示)。
- [ここ](https://kujirahand.com/web-tools/Hex.php)で変換表示。
- 「16進数(HEX)形式のフレーズを入力」の欄に入力して「デコード」ボタンで変換して確認する。


#おつかれさまでした

2018-2019の年末年始は休みが長かったですね。
ヒマだったのでずっとやろうと思っていたマイナンバーカードの検証をすることができました。
先人の取り組みで大変参考になるものが多く、行き詰まることもありませんでした。

マイナンバーカードは認証とか署名のデバイスとしてはとてもいいものだと思うのですが、額面に個人情報表記しすぎなのとか公式な仕様が見当たらない（オープンにしてない？なんで？）などなんか残念です。
今の時代これを持ち歩く人はいないんじゃないかな。