マイナンバーカードの電子証明書(公的個人認証サービス)にJava APIでアクセスする

本記事では、マイナンバーカード(個人番号カード)に搭載されている電子証明書(公的的個人認証サービス)にJavaプログラムからアクセスする方法を見ていきます。

【目次】

[1]はじめに

最近何かと話題のマイナンバーカードですが、本記事では、マイナンバーカードに搭載されている電子証明書(公的的個人認証サービス)にプログラムからアクセスする方法を見ていきます。

公的個人認証サービスのリーフレットには、以下のように書かれています。
  • 誰もが安心してオンライン手続きを行うには、他人を装って虚偽の申請を行う「なりすまし」や、第三者が送信されたデータを書き換える「改ざん」などへの対策が必要です。
  • 公的個人認証サービスは「なりすまし」や「改ざん」を防ぎ、インターネットを通じて安全・確実な行政手続き等を行うための機能を電子証明書という形で提供しています。
  • 電子証明書は、市区町村窓口において取得でき、個人番号カード(番号カード)内に記録されます。
  • 電子証明書には、利用者証明用証明書と署名用電子証明書の2種類があります。電子申請・申告には、署名用電子証明書が必要です

ここで個人番号カードとはマイナンバーカードのことです。そして、マイナンバーカードには2つの電子証明書が記録されています。
  • 署名用電子証明書
    • インターネット等で電子文書を作成・送信する際に利用します。
      • 「作成・送信した電子文書が、利用者が作成した真正なものであり、利用者が送信したものであること」を証明することができます。
    • 基本4情報(氏名、住所、生年月日、性別)が記録されていますので、結婚や引っ越しなどで氏名や住所に変更があると、証明書が失効します。
    • e-Tax等の電子申請・申告などで利用します。
  • 利用者証明用証明書
    • インターネットサイトやコンビニ等のキオスク端末等にログインする際に利用します。
      • 「ログインした者が、利用者本人であること」を証明することができます。
    • 署名用電子証明書とは異なり、基本4情報が記録されていないため、氏名や住所に変更があっても失効せず、そのまま利用できます。
    • マイナポータルへのログイン、コンビニでの住民票などの公的な証明書の交付などで利用します。

名前がややこしいですが、2つの大きな違いは基本4情報(氏名、住所、生年月日、性別)が記録されているかどうかによる効力の違いと思います。

とはいいつつ、実際に利用する際には、証明書の違いより、この2つの証明書にアクセスするためのパスワードの違いの方が強く意識されるように思います(笑)。

ちなみに、「署名用電子証明書については5回連続で、利用者証明用電子証明書については3回連続でパスワードを間違って入力した場合、パスワードロックがかかってしまい、当該電子証明書は利用できなくなってしまいます。」とあります。緊張しますね。。。

より詳細な情報については、以下のサイトなどを参照して下さい。

また、公的個人認証のようなPKIの一般的な技術概要については以下のサイトが参考になると思います。

本記事では、Windows環境で、利用者クライアントソフトを利用してマイナンバーカードにアクセスできることを確認することからはじめます。利用者クライアントソフトをインストールすると、外部プログラムから利用可能なライブラリもインストールされます。これを用いてプログラムから電子証明書にアクセスする方法を見ていきます。

(2021/5/16追記)
マイナンバーカードを利用した電子署名と検証について、以下の記事を書きましたので、宜しければ参考にしてください。

(注意)
本記事の内容は、電子証明書が搭載されたマイナンバーカードが対象です。
マイナンバーカードの交付申請をする際に、電子証明書が不要であるとした場合は、電子証明書が搭載されていないカードが発行されるようです。(ややこしいですね。。。)

[2]事前準備(利用者クライアントソフトで動作確認)

まず、公的個人認証サービスポータルサイトで配布されている利用者クライアントソフトを使って、電子証明書の内容を見ることができることを確認します。これはプログラムからアクセスする際のテストにも役立ちます。

(1)ICカードリーダライタの準備

最初の難関?が、ICカードリーダライタの準備かもしれません。対応機種やドライバなどについては、以下のサイトを参照して下さい。
ここには、「Windowsパソコンについては、対応するAndroid端末をICカードリーダライタとして公的個人認証サービスを利用することが可能です。」と書かれていますので、Android端末をお持ちの方はICカードリーダライタを購入する必要はないかもしれません。
(私はAndroid端末を持っていないため、未確認です。)

(2)利用者クライアントソフトのインストール

続いて、以下のサイトからWindows版利用者クライアントソフトをダウンロードしてインストールします。
インストールが完了すると、Windowsのメニューに「公的個人認証サービス」が作成されていると思います。(名前のつながりがややこしい。。。)

(3)利用者クライアントソフトの動作確認

Webサイトでは「利用者クライアントソフト」となっていますが、起動するソフトの名称は「JPKI利用者ソフト」です(笑)。

このソフトの利用方法は難しいものではないと思いますが、例えばマイナンバーカードを準備して「自分の証明書」ボタンをクリックしても、エラーになって電子証明書の内容が表示されない場合もあります。
このような場合の簡単なチェック事項を書いてみます。
  • 「JPKI利用者ソフト」の「動作確認」を実行して、エラー内容から原因を推測する(分かり難いと思いますけど)。
  • Windowsメニューの「公的個人認証サービス」にある「ICカードリーダライタ設定」を起動して、種類を明示的に指定してみる。
  • ICカードリーダライタのドライバが最新のものかどうか確認してみる。
  • 接触型ICカードリーダライタを利用している場合、カードの挿入方法が間違っていないか確認する。
    • カードの裏面(個人番号が書かれている面)を上にして矢印の方向にカードを挿入する、など。

[3]APIについて

(1)仕様の構成

利用者クライアントソフトをインストールすると、外部プログラムから電子証明書にアクセスするためのライブラリもインストールされます。

このライブラリの仕様は以下のサイトで公開されています。

仕様書の中には「ソフトウェア構成図」が示されており、構成要素ごとの仕様書があります。
以下の図はソフトウェア構成図をざっくり簡略化したものです。

JPKIソフトウェア構成図

ここで、上位アプリケーションとは、利用者クライアントソフトや自分で作成するプログラムのことです。
上位アプリケーションは、「カード AP ライブラリ」と「個人認証サービス AP」というライブラリを利用して、マイナンバーカードにアクセスしたり、電子証明書の検証などを行うことができます。

2つのライブラリの概要は以下の通りです。
  • カード AP ライブラリ
    • 「証明書取得機能」「電子署名生成機能」「電子署名検証機能」を実現する API 
    • CryptoAPI、 PKCS#11、 Java インターフェースがある。
      • JavaインターフェイスはCryptoAPIのラッパー。
  • 個人認証サービス AP
    • 「証明書表示機能」「基本4情報取得機能」「官職証明書検証機能」「自己の電子証明書の有効性確認機能」「IC カード種別取得機能」を実現する API
    • C 言語インターフェースと Javaインターフェースがある。
      • JavaインターフェイスはC言語インターフェイスのラッパー。

(2)Javaインターフェイスの仕様

本記事では、Javaインターフェイスを利用して電子証明書にアクセスする例を見ていきます。
上記の「利用者クライアントソフトに係る技術仕様について」のサイトにある仕様のうち、主に以下の仕様書が参考になります。
  • 利用者クライアントソフト機能概要説明書
  • カードAPライブラリJavaインターフェース編とJavadoc
  • 個人認証APライブラリJavaインターフェース編とJavadoc
  • Jarファイル利用手引き
  • 署名用電子証明書及び利用者証明用電子証明書のプロファイル仕様書

(3)Javaライブラリ(クラスパス)の設定

利用者クライアントソフトをインストールすると、%ProgramFiles%¥JPKILib¥Javalib64 ディレクトリに以下のJARファイルが配置されています。
  • JPKICryptSignJNI.jar
    • マイナンバーカードの署名用電子証明書に対するカードAPライブラリ
  • JPKICryptAuthJNI.jar
    • マイナンバーカードの利用者証明用電子証明書に対するカードAPライブラリ
  • JPKICryptJNI.jar
    • 住基カードの署名用電子証明書に対するカードAPライブラリ
  • JPKIUserCertService.jar
    • 個人認証APライブラリ

プログラムから利用する場合は、(必要に応じて)上記のJARファイルにクラスパスを通してください。

[4]JavaのカードAPライブラリを利用して電子証明書を取得

ここでは、JavaのカードAPライブラリを利用してカード内に格納されている電子証明書を取り出す方法を見ていきます。
(なお、カードAPライブラリには、証明書取得機能以外に、電子署名生成機能と電子署名検証機能がありますが、本記事では割愛します。)

カードAPライブラリでは、マイナンバーカードの署名用電子証明書と利用者証明用電子証明書に加えて、住基カードの電子証明書もサポートされています(Windows版のみ)。

以下に電子証明書の取得手順を確認することを目的としたサンプルコードを書きます。
各APIの詳細については、カードAPライブラリJavaインターフェース編のJavadocを参照して下さい。
(カードAPライブラリのJavaインターフェイスはCryptoAPIのラッパーとなっているため、CryptoAPIをご存知の方はイメージしやすいかもしれません。)

また、実際に利用する際には、利用用途に応じて例外処理の追加やクラス構成などを検討して下さい。

(1)マイナンバーカードの署名用電子証明書(JPKICryptSignJNI)

署名用電子証明書とそのルート証明書を取得できます。
利用する場合は、JPKICryptSignJNI.jar にクラスパスを通します。

署名用電子証明書の取得

以下のコードを実行すると、「個人番号カード ログイン」画面が表示されますので、ここで署名用パスワードを入力すると電子証明書を取得できます。(証明書に基本4情報を含むため、パスワードによる認証が必要とされているように思います。逆にいえば、ICカードがあってもパスワードを知っている人(例えば本人)しか証明書を見ることができません。)

キャンセルすると、JPKICryptSignJNIException 例外がスローされます。

/**
 * 署名用電子証明書の取得サンプル
 * 
 * @return
 * @throws JPKICryptSignJNIException
 */
public static byte[] getSignCertificateValue_Sample() throws JPKICryptSignJNIException {
    JPKICryptSignJNI jni = new JPKICryptSignJNI();
    // (1)プロバイダハンドルを取得
    // パスワードを入力するダイアログが表示される
    long hProvider = jni.cryptAcquireContext(0);
    try {
        // (2)プロバイダの秘密鍵ハンドルを取得
        long hKey = jni.cryptGetUserKey(hProvider);
        try {
            // (3)秘密鍵に対応する利用者証明書を取得
            return jni.cryptGetCertificateValue(hKey);
        } finally {
            // (4)鍵ハンドルを解放
            jni.cryptDestroyKey(hKey);
        }
    } finally {
        // (5)プロバイダハンドルを解放
        jni.cryptReleaseContext(hProvider);
    }
}

署名用電子証明書のルート証明書(自己署名証明書)の取得

以下のコードを実行すると、パスワード入力画面が表示されること無くルート証明書を取得できます。

/**
 * 署名用認証局の自己署名証明書の取得サンプル
 * @return
 * @throws JPKICryptSignJNIException
 */
public static byte[] getSignRootCertificateValue_Sample() throws JPKICryptSignJNIException{
    JPKICryptSignJNI jni = new JPKICryptSignJNI();
    //(1)プロバイダハンドルを取得
    // 引数にJPKICryptAuthJNI.JPKI_VERIFYCONTEXTを指定できるのでパスワード不要で取得できる
    long hProvider  = jni.cryptAcquireContext(JPKICryptAuthJNI.JPKI_VERIFYCONTEXT);
    try {
         //(2)署名用認証局の自己署名証明書を取得
        return jni.cryptGetRootCertificateValue(hProvider);
    } finally {
        //(3)プロバイダハンドルを解放
        jni.cryptReleaseContext(hProvider);
    }
}

(2)マイナンバーカードの利用者証明用電子証明書( JPKICryptAuthJNI)

利用者証明用電子証明書とそのルート証明書を取得できます。
利用する場合は、JPKICryptAuthJNI.jar にクラスパスを通します。

利用者証明用電子証明書の取得

以下のコードを実行すると、「個人番号カード ログイン」画面が表示されますので、ここで利用者証明用パスワードを入力すると電子証明書を取得できます。
キャンセルするとJPKICryptAuthJNIException 例外がスローされます。

といいつつ、API仕様のサンプルではcryptAcquireContextの引数に0を指定していますが、試してみるとJPKICryptAuthJNI.JPKI_VERIFYCONTEXTでも動作するようです。この場合はパスワード入力画面が表示されることなく電子証明書を取得できます。
これは公式な動作かどうかわかりませんが、利用者証明用電子証明書には基本4情報を含まないため、ルート証明書と同様にパスワード認証が不要なのかもしれません。。。

/**
 * 利用者証明用電子証明書の取得サンプル
 * @return
 * @throws JPKICryptAuthJNIException
 */
public static byte[] getAuthCertificateValue_Sample() throws JPKICryptAuthJNIException{
    JPKICryptAuthJNI jni = new JPKICryptAuthJNI();
    //(1)プロバイダハンドルを取得
    // パスワードを入力するダイアログが表示される
    long hProvider  = jni.cryptAcquireContext(0);
    // API仕様サンプルでは引数に0を指定している(パスワードの入力が必要になる)が、
    // JPKICryptAuthJNI.JPKI_VERIFYCONTEXTを指定しても取得できるみたい
    // (この場合、パスワード入力は不要)
    //long hProvider  = jni.cryptAcquireContext(JPKICryptAuthJNI.JPKI_VERIFYCONTEXT);
    try {
        //(2)プロバイダの秘密鍵ハンドルを取得
        long hKey = jni.cryptGetUserKey(hProvider);
        try {
             //(3)秘密鍵に対応する利用者証明書を取得
            return jni.cryptGetCertificateValue(hKey);
        } finally {
            //(4)鍵ハンドルを解放
            jni.cryptDestroyKey(hKey);
        }
    } finally {
        //(5)プロバイダハンドルを解放
        jni.cryptReleaseContext(hProvider);
    }
}

利用者証明用電子証明書のルート証明書(自己署名証明書)の取得

以下のコードを実行すると、パスワード入力画面が表示されること無くルート証明書を取得できます。

/**
 * 利用者証明用電子証明書の自己署名証明書の取得サンプル
 * @return
 * @throws JPKICryptAuthJNIException 
 */
public static byte[] getAuthRootCertificateValue_Sample() throws JPKICryptAuthJNIException{
    JPKICryptAuthJNI jni = new JPKICryptAuthJNI();
    //(1)プロバイダハンドルを取得
    // 引数にJPKICryptAuthJNI.JPKI_VERIFYCONTEXTを指定できるのでパスワード不要で取得できる
    long hProvider  = jni.cryptAcquireContext(JPKICryptAuthJNI.JPKI_VERIFYCONTEXT);
    try {
         //(2)署名用認証局の自己署名証明書を取得
        return jni.cryptGetRootCertificateValue(hProvider);
    } finally {
        //(3)プロバイダハンドルを解放
        jni.cryptReleaseContext(hProvider);
    }
}

(3)住基カードの署名用電子証明書を取得 (JPKICryptJNI)

「平成28年1月からマイナンバーカードが発行開始されたことに伴い、住基カードの発行は平成27年12月で終了しています。」

今となっては利用する局面があるのかどうかわかりませんが、住基カードの電子証明書を取り出すAPIも残されています(但しWindows版のみ)。

利用する場合は、JPKICryptJNI.jar にクラスパスを通します。

住基カードの署名用電子証明書の取得

以下のコードを実行すると、「住基カード ログイン」画面が表示されますので、ここで署名用パスワードを入力すると電子証明書を取得できます。(証明書に基本4情報を含むため、パスワードによる認証が必要とされていると思います。)
キャンセルすると、JPKICryptJNIException 例外がスローされます。

/**
 * 住基カードに格納された署名用電子証明書の取得サンプル
 * @return
 * @throws JPKICryptJNIException 
 */
public static byte[] getJyukiCertificateValue_Sample() throws JPKICryptJNIException{
    JPKICryptJNI jni = new JPKICryptJNI();
    //(1)プロバイダハンドルを取得
    // パスワードを入力するダイアログが表示される
    long hProvider  = jni.cryptAcquireContext(0);
    try {
        //(2)プロバイダの秘密鍵ハンドルを取得
        long hKey = jni.cryptGetUserKey(hProvider);
        try {
             //(3)秘密鍵に対応する利用者証明書を取得
            return jni.cryptGetCertificateValue(hKey);
        } finally {
            //(4)鍵ハンドルを解放
            jni.cryptDestroyKey(hKey);
        }
    } finally {
        //(5)プロバイダハンドルを解放
        jni.cryptReleaseContext(hProvider);
    }
}

住基カードのルート証明書(都道府県知事の自己署名証明書)の取得

以下のコードを実行すると、パスワード入力画面が表示されること無くルート証明書を取得できます。

/**
 * 住基カードに格納された署名用電子証明書の都道府県知事の自己署名証明書の取得サンプル
 * @return
 * @throws JPKICryptJNIException 
 */
public static byte[] getJyukiRootCertificateValue_Sample() throws JPKICryptJNIException{
    JPKICryptJNI jni = new JPKICryptJNI();
    //(1)プロバイダハンドルを取得
    // 引数にJPKICryptAuthJNI.JPKI_VERIFYCONTEXTを指定できるのでパスワード不要で取得できる
    long hProvider  = jni.cryptAcquireContext(JPKICryptAuthJNI.JPKI_VERIFYCONTEXT);
    try {
         //(2)署名用認証局の自己署名証明書を取得
        return jni.cryptGetRootCertificateValue(hProvider);
    } finally {
        //(3)プロバイダハンドルを解放
        jni.cryptReleaseContext(hProvider);
    }
}

[5]電子証明書の扱い

マイナンバーカードから取り出した電子証明書は、日本工業規格 X560-1 の識別符号化規則により符号化された形式(DER(Distinguished Encoding Rules)形式)のバイナリデータです。このため、PKI関係の汎用ライブラリ等で利用することができます。

各電子証明書のレイアウトは以下の仕様書に記載されています。

ところで、Windowsでは、拡張子が.cer等の証明書ファイルをダブルクリックすると、証明書の画面が表示され、証明書の内容を見ることができます。
例えば、上記サンプルコードで取得した署名用電子証明書を、「cert.cer」としてファイルに保存してみます。

byte[] cert = getSignCertificateValue_Sample();
Files.write(Paths.get("cert.cer"), cert);

エクスプローラーから「cert.cer」をダブルクリックすると、証明書画面が表示されると思います。
しかしながら、Windowsの証明書画面では、署名用電子証明書のプロファイル拡張領域に格納されている基本4情報がバイナリデータとして表示されるため、そのままでは基本4情報の内容を確認することができません。
また、公的個人認証の電子証明書は、有効性確認に関する情報(例えばCRLやOCSP等)が非公開のため、汎用のPKIライブラリ等で有効性確認を行うこともできません。

このような、電子証明書から基本4情報を取り出したり、電子証明書有効性確認を行う場合は、後述の個人認証サービスAPを利用するのが簡単です。

[6]Javaの個人認証サービス APを利用する

Javaの個人認証サービス APを利用すると、カードAPライブラリで取得した電子証明書の表示や有効性確認、基本4情報の取得を行うことができます。(ICカード種別取得機能もあります。)

使い方は簡単で、基本的には、JPKIUserCertService クラスのコンストラクタに処理したい証明書を与えてインスタンスを生成し、目的のメソッドを呼び出すだけです。

詳細な仕様は、「個人認証APライブラリJavaインターフェース編」とJavadocを参照して下さい。

なお、利用する場合は、JPKIUserCertService.jar にクラスパスを通しておく必要があります。

(1)電子証明書の表示(showCertViewer)

JPKIUserCertService クラスのコンストラクタに電子証明書のバイナリデータを与えてインスタンス化して showCertViewer メソッドを呼び出すと、電子証明書の種類に応じた項目が表示されます。

表示される画面は、JPKI利用者ソフトの証明書表示画面と同じです。
/**
 * 証明書表示
 * @param cert
 */
public static void sohwCert_Sample(byte[] cert) {
    JPKIUserCertService ucs = new JPKIUserCertService(cert);
    try {
        ucs.showCertViewer();
    } catch (JPKIUserCertException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

例えば、以下のコードでマイナンバーカードの署名用電子証明書を表示できます。(なお、ファイルに保存された証明書データなども利用可能です。)

byte[] cert = getSignCertificateValue_Sample();
sohwCert_Sample(cert);

基本4情報の表示に加えて、ファイル出力や有効性確認も行うことができます。

補足ですが、「ファイル出力」ボタンをクリックして表示される「名前を付けて保存」画面で、ファイルの種類を選択することができます。
  • 拡張子を.txtで保存する:ファイルの種類「基本情報ファイル(*.txt)」
    • 基本4情報に加えて発行日や有効期限、発行者がテキストとして出力されます。
  • 拡張子を.cerで保存する:ファイルの種類「証明書ファイル(*.cer)」
    • DER形式で出力されます。(JPKIUserCertServiceの引数に与えたデータと同じ内容が出力されます。)

なお、画面を表示しなくても、後述のAPIを利用すれば、基本4情報の取り出しや有効性確認を行うことができます。

(2)署名用電子証明書から基本4情報を取得(getBasicData)

JPKIUserCertService クラスのコンストラクタに署名用電子証明書のバイナリデータを与えてインスタンス化して getBasicData メソッドを呼び出すと、基本4情報(JPKIUserCertBasicData)を取り出すことができます。

// 署名用電子証明書を取得
byte[] signCert =  getSignCertificateValue_Sample();

// 基本4情報取得機能
JPKIUserCertService ucs = new JPKIUserCertService(signCert);
JPKIUserCertBasicData res = ucs.getBasicData();
//
System.out.println("getAddress(住所)=" + res.getAddress());
System.out.println("getDateOfBirth(生年月日)=" + res.getDateOfBirth());
System.out.println("getGender(性別)=" + res.getGender());
System.out.println("getName(氏名)=" + res.getName());
System.out.println("getSubstituteCharacterOfName(住所の代替文字)=" + res.getSubstituteCharacterOfName());
System.out.println("getSubstituteCharacterOfAddress(氏名の代替文字)=" + res.getSubstituteCharacterOfAddress());

このコードは、JPKIUserCertBasicDataを単純に表示するだけのサンプルですが、実際の出力結果を見ると、証明書表示画面の内容と少し異なるところがあると思います。
例えば、日付のフォーマットや性別、文字表示などです。

これらの詳細については、以下の仕様書に説明があります。
  • 利用者クライアントソフト機能概要説明書
    • 第5章 機能概要(個人番号カード編) .4 画面仕様 以降の記述
  • 個人認証APライブラリJavaインターフェース編 javadocの説明
  • 各種証明書のプロファイル仕様書

(3)利用者証明書の有効性確認(confirm)

証明書表示画面の「有効性確認」ボタンをクリックすると、電子証明書の有効性確認を行うことができますが、画面を経由せず、APIを利用して有効性確認を行うことができます。

JPKIUserCertService クラスのコンストラクタに署名用電子証明書または利用者証明用証明書のバイナリデータを与えてインスタンス化して confirm メソッドを呼び出すと、「個人番号カード ログイン」画面が表示され、証明書に応じたパスワードを入力すると、有効性確認の結果を得ることができます。
(パスワードによる認証が必要ということは、ICカードがあってもパスワードを知っている人(例えば本人)しか電子証明書の有効性確認はできません。)

/**
 * 利用者証明書の有効性確認
 * @param cert
 */
public static void confirmEECert_Sample(byte[] cert) {
    JPKIUserCertService ucs = new JPKIUserCertService(cert);
    try {
        // 有効性確認
        JPKIConfirmResult res = ucs.confirm();
        // 結果メッセージの取得
        String msg = res.getMessage();
        // 結果の取得
        int code = res.getCode();
        switch (code) {
        // 有効
        case JPKIConfirmResult.JPKI_CONFIRM_OK:
            System.out.println("JPKI_CONFIRM_OK/code=" + code + ",msg=" + msg);
            break;
        // 無効 (有効期限切れ)
        case JPKIConfirmResult.JPKI_CLIENT_EXPIRED_ERROR:
            System.out.println("JPKI_CLIENT_EXPIRED_ERROR/code=" + code + ",msg=" + msg);
            break;
        // 無効 (失効済)
        case JPKIConfirmResult.JPKI_SERVER_REVOKED_ERROR:
            System.out.println("JPKI_SERVER_REVOKED_ERROR/code=" + code + ",msg=" + msg);
            break;
        // 無効 (失効申請中)
        case JPKIConfirmResult.JPKI_SERVER_APPLYED_ERROR:
            System.out.println("JPKI_SERVER_APPLYED_ERROR/code=" + code + ",msg=" + msg);
            break;
        // 無効(一時保留)
        case JPKIConfirmResult.JPKI_SERVER_HOLD_ERROR:
            System.out.println("JPKI_SERVER_HOLD_ERROR/code=" + code + ",msg=" + msg);
            break;
        // 有効性確認失敗
        default :
             // 有効性確認中に発生したExceptionの取得 
            Exception ex = res.getException();
            // サーバ要因エラー,HTTP通信エラー
            if(ex == null){
                // ・サーバ要因エラー(JPKIConfirmResultフィールド値:600番台)
                // ・HTTP通信エラー  (HTTPステータスコード:100~500番台)
                // の場合の処理
                System.out.println("サーバ要因エラー,HTTP通信エラー,msg=" + msg);
              // クライアント要因エラー
            }else{
                System.out.println("クライアント要因エラー,msg=" + msg + ", ex.getMessage=" + ex.getMessage());
                ex.printStackTrace();
            }
            break;
        }
    } catch (JPKIUserCertException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

有効な場合は話が単純ですが、無効な場合はその理由が重要な場合もあります。また、有効か無効かが判断できない場合(エラー、例外の場合)は、原因が分かり難い場合もありますので、Javadocなどを参考にして考えられるエラーを整理して対応する必要があるかもしれません。

(4) ICカードリーダライタに挿入されているICカードの種別を取得(getCardType)

最後に、おまけのようなものかもしれませんが、ICカードリーダライタに挿入されているICカードの種別を取得する機能があります。

この機能は証明書を利用しないため、引数無しのコンストラクタで JPKIUserCertService クラスのインスタンスを作成して利用できます。

ただ、この機能は、正常にICカード種別が得られた場合より、例外がスローされた場合の情報のほうが、トラブル対応に役立つような気がします。。。

/**
 * ICカードリーダライタに挿入されているICカードの種別を取得
 */
public static void printCardType_Sample() {
    JPKIUserCertService ucs = new JPKIUserCertService();
    try {
        // ICカード種別取得
        JPKICardType cardType = ucs.getCardType();
        int id = cardType.getID();
        String idInfo ="";
        if (id == JPKICardType.JPKI_CARD_ID_JYUKI) {
            // 住基カードの場合
            idInfo = "住基カード id=" + id;
        }
        else if (id == JPKICardType.JPKI_CARD_ID_BANGO) {
            // 個人番号カードの場合
            idInfo = "個人番号カード id=" + id;
        }
        else if (id == JPKICardType.JPKI_CARD_ID_UNKNOWN) {
            // 不明の場合
            idInfo = "不明 id=" + id;
        }
        // ICカードtoken情報
        String tokenInfo = cardType.getTokenInfo();
        
        System.out.println(idInfo + ", tokenInfo=" + tokenInfo);
    } catch (JPKIUserCertException e) {
        // JPKIUserCertException 発生時の処理
        e.printStackTrace();
    } catch (Exception e) {
        // その他のException発生時の処理
        e.printStackTrace();
    }
}

コメント

このブログの人気の投稿

VirtualBoxのスナップショット機能

Google Document AIで画像から表形式データを抽出する(Vision API OCRとの違い)

Ubuntu/Colab環境でPDFファイルのページを画像化する(pdf2image、pdftoppm、pdftocairo)