マイナポイント(5000円相当)を貰おう(3)、開発編




技術トピックス・マイカード

電子証明書の種類

引用元1:マイナンバーカードに「電子証明書」があるって知ってた?
引用元2:電子証明書(各種証明書のコンビニ交付、e-Taxなどの電子申請)について

「電子証明書」とは、公的個人認証サービスとして信頼できる第三者(認証局)が間違いなく本人であることを電子的に証明するもの。書面取引における印鑑証明書に代わるものだ。「電子証明書」と呼ばれるデータを、外部から読み取られる恐れのない、マイナンバーカードなどのICカードに記録することで利用可能となる。

電子証明書には「署名用電子証明書」と「利用者証明用電子証明書」の2種類がある。マイナンバーカードでは、発行申請時にこれらの搭載を「希望しない場合のみ不要の□を黒く塗りつぶす」ことになっているため、原則として標準搭載されているはずだ。

○利用者証明用電子証明書(各種証明書のコンビニ交付)

  全国のコンビニエンスストア(セブン-イレブン・ローソン・ファミリーマート・ミニストップ等)にあるマルチコピー機で年末年始を除く毎日午前6時30分から午後11時まで住民票の写しや印鑑登録証明書が取得できます。
  また、行政のサイト(マイナポータル等)へのログイン時に利用者本人であることを証明する手段として使用します。
  利用者証明用電子証明書の有効期限は発行日より5回目の誕生日までとなります。
  暗証番号は4桁の数字で設定し、入力を3回誤るとロックがかかってしまいます。

  ※印鑑登録証明書は、印鑑登録されており、カード式の印鑑登録証をお持ちの方のみ取得できます。

○署名用電子証明書(e-Taxなどの各種電子申請)

  国税電子申告・納税システム(e-Tax)等の各種電子申請を行うことができます。(利用できる行政手続きは公的個人認証サービスポータルサイト(外部サイトへリンク)をご覧ください。)
  インターネット等で電子文書を作成・送信する際に利用され、作成・送信した電子文書が利用者が作成した真正なものであり、利用者が送信したものであることを証明します。
  署名用電子証明書の有効期限は発行日から最長5年間ですが、マイナンバーカードの券面に記載されている有効期限や利用者証明用電子証明書の有効期限(証明書発行日から5回目の誕生日まで)が先にくる場合はその有効期限までとなります。また氏名や住所等に変更が生じた場合は失効いたします。
  暗証番号は数字と英字(大文字のみ)を混在させ6桁から16桁の中で設定し、入力を5回誤るとロックがかかってしまいます。

マイナンバーカード開発ドキュメント

  ○「利用者クライアントソフトに係る技術仕様について」!以下をクリック:
  ※地方公共団体情報システム機構: 技術仕様
以下の内容は上記から引用します。

利用者クライアントソフトに係る技術仕様について
ここから本文
 利用者クライアントソフトは、公的個人認証サービスが提供する電子証明書をパソコン及びAndroid上で取
り扱うソフトウェアを開発するためのライブラリです。

 1)カードAPライブラリ(PC版)
  電子署名に係る機能について、CryptAPI、PKCS#11、Javaの3種類のインタフェースを提供しています。
   ・証明書取得機能
   ・電子署名生成機能
   ・電子署名検証機能

 2)個人認証サービスAPライブラリ(PC版)
  電子署名以外に係る機能について、C、Javaの2種類のインタフェースを提供しています。
   ・証明書表示機能
   ・基本4情報取得機能
   ・官職証明書検証機能
   ・自己の電子証明書の有効性確認機能
   ・ICカード種別取得機能

 3)Android用仕様書
  Android用のインテントによる外部インテントインタフェースを提供しています。
   ・証明書取得機能
   ・電子署名生成機能
   ・電子署名検証機能
   ・証明書表示機能
   ・基本4情報取得機能
   ・官職証明書検証機能
   ・自己の電子証明書の有効性確認機能
   ・ICカード種別取得機能

利用者クライアントソフトに係る技術仕様書等は、以下からダウンロードできます。

○利用者クライアントソフト仕様書(PC版)
 利用者クライアントソフト機能概要説明書 第4.4版(3,134kbyte)pdf
  └利用者クライアントソフトAPI仕様書
     ├カードAPライブラリCryptoAPI編_第4.4版(193kbyte)pdf
     ├カードAPライブラリPKCS#11編_第4.4版(321kbyte)pdf
     ├カードAPライブラリJavaインターフェース編_第4.4版(74kbyte)pdf
        └Javadoc(ZIP) (316kbyte)
     ├個人認証APライブラリC言語インターフェース編_第4.4版(437kbyte)pdf
     ├個人認証APライブラリJavaインターフェース編_第4.4版 (70kbyte)pdf
        └Javadoc(ZIP) (70kbyte)
     ├Jarファイル利用手引き第1.0版(78kbyte)pdf

(本仕様書は、利用者クライアントソフトVer03-03に対応しています)

○利用者クライアントソフトヘッダファイル(PC版)
 ・利用者クライアントソフト_開発用ヘッダファイル(ZIP)(3kbyte)

○利用者クライアントソフト仕様書(Android版)
 利用者クライアントソフト機能概要説明書_1.4版 (2,036kbyte)pdf
  └利用者クライアントソフト_API仕様書
     └Androidインテント編_1.4版(PDF) (670kbyte)pdf

○各種証明書のプロファイル仕様書
 ・署名用電子証明書及び利用者証明用電子証明書のプロファイル仕様書_2.0版(PDF)(159kbyte)

○本資料は、改変、転載、複製を禁じます。

以下の仕様書は、当機構と協定書を締結した署名検証者(第17条第1項)、利用者証明検証者(第36条第1項)、
団体署名検証者(第17条第5項)及び第17条第1項第5号又は第36条第1項の規定に基づき総務大臣に認定の申請を行った者のみ開示可能です。

○利用者クライアントソフト 機能概要説明書 ブラウザ対応編
 └API仕様書 カードAPライブラリ ブラウザインターフェース編

○利用者クライアントソフト 機能概要説明書(iOS版)
 └API仕様書 iOS Framework編

なおブラウザインタフェース用のドキュメントは、別途契約が必要です。
従って今回は、ブラウザインタフェース用のアプリではなく、スタンドアロンアプリのみ作成します。

マイナンバーカードAPI Javadocs

クラス名    説明 jarファイル
1.JPKICardType
2.JPKIConfirmResult
3.JPKIUserCertBasicData
4.JPKIUserCertCertPathStatus
5.JPKIUserCertCertStatus
6.JPKIUserCertException
7.JPKIUserCertResponseStatus
8.JPKIUserCertService
1.ICカード種別の情報を管理します。
2.利用者証明書有効性確認機能で使用する確認結果を管理します。
3.公的個人認証サービスの利用者証明書の基本4情報を管理します。
4.官職証明書検証機能で使用するCertPathStatusを定義します。
5.官職証明書検証機能で使用する検証結果を管理します。
6.個人認証サービスAPでエラーが発生した場合
7.官職証明書検証機能で使用するResponseStatusを定義します。
8.個人認証サービスAPの証明書表示機能、基本4情報取得機能、官職証明書検証機能、 利用者証明書有効性確認機能、ICカード種別取得機能を提供します。
JPKIUserCertService.jar
JPKICryptJNI カードAPライブラリ(CryptoAPI版(住基カード署名利用の場合))に対するJNIクラスを提供します。 JPKICryptJNI.jar
JPKICryptSignJNI カードAPライブラリ(CryptoAPI版(個人番号カード署名利用の場合))に対するJNIクラスを提供します。 JPKICryptSignJNI.jar
JPKICryptAuthJNI カードAPライブラリ(CryptoAPI版(個人番号カード利用者証明利用の場合))に対するJNIクラスを提供します。 JPKICryptAuthJNI.jar

○Javaパッケージ/クラス仕様書
※Javadocsを展開して、WEBサーバに登録した
※例:http://127.0.0.1//JPKIUserCertService%20javadoc/

Java言語環境

○Javaコンパイラ環境
  C:\Program Files\Java配下
  ○開発環境:C:\Program Files\Java\jdk-11.0.10
  ○実行環境:C:\Program Files\Java\jre1.8.0_281

○Javaソース環境
  C:\Users\Public\acer\E 佳昭配下BACKUP\13.トリニタス社仕事\java

○コンパイル(javac)と実行(java)
  ・コンパイル:javac -classpath “%ProgramFiles%\JPKILib\Javalib64\JPKICryptSignJNI.jar;%ProgramFiles%\JPKILib\Javalib64\JPKIUserCertService.jar” CryptSignValidate.java
  ・実行:java -classpath “%ProgramFiles%\JPKILib\Javalib64\JPKICryptSignJNI.jar;%ProgramFiles%\JPKILib\Javalib64\JPKIUserCertService.jar;./” CryptSignValidate

○Javaソース
  IcCardType.java:ICカード判別機能
  CryptAuth.java:利用者電子証明書の機能
    「パスワード確認」「基本情報表示」「詳細情報」
  CryptSign.java:署名用電子証明書の機能
    「パスワード確認」「基本情報表示」「詳細情報」「基本4情報(署名用のみ)」
  CryptAuthValidate.java:利用者電子証明書の検証
  CryptSignValidate.java:署名用電子証明書の検証

IcCardType.java
  「ICカード判別機能」
  セットされたICカードが「住基カード」「マイナンバーカード」かチェックする


CryptAuth.java
  「パスワード確認」
  「基本情報表示」
  「詳細情報」


CryptSign.java
  「パスワード確認」
  「基本情報表示」
  「詳細情報」
  「基本情報4情報表示」


CryptAuthValidate.java
  「利用者電子証明書の検証」

CryptSignValidate.java
  「署名用電子証明書の検証」

○提供されるJavaクラス・ライブラリ(jarファイル)
  ・所在:C:\Program Files\JPKILib\Javalib64配下
  ※64bit版のみ使用する
・jarファイル:
  ・JPKICryptAuthJNI.jar 利用者電子証明書関連
  ・JPKICryptJNI.jar 住基カード署名利用
  ・JPKICryptSignJNI.jar 署名用電子証明書関連
  ・JPKIUserCertService.jar 基本情報取得、証明書検証等

このクラスのメソッドを組み合わせて使用することで、以下の処理を実装することができます。
  (1)利用者証明用認証局の自己署名証明書取得処理
  (2)利用者証明書取得処理
  (3)電子署名作成処理(署名対象データを渡す場合)

  上記の(2)をクリックするとコーリングシーケンスが記載されています:

    JPKICryptAuthJNI jpkiCryptAuth = new JPKICryptAuthJNI();

    //(1)プロバイダハンドルを取得
    long hProv = jpkiCryptAuth.cryptAcquireContext(0);

    //(2)プロバイダの秘密鍵ハンドルを取得
    long hKey = jpkiCryptAuth.cryptGetUserKey(hProv);

    //(3)秘密鍵に対応する利用者証明書を取得
    byte[] bCert = jpkiCryptAuth.cryptGetCertificateValue(hKey);

    //(4)鍵ハンドルを解放
    jpkiCryptAuth.cryptDestroyKey(hKey);

    //(5)プロバイダハンドルを解放
    jpkiCryptAuth.cryptReleaseContext(hProv);

C言語環境(参考)

以下「C言語」で開発する場合の開発環境設定、実行環境設定の方法です、当初はC言語で開発していましたが
、Java環境で動作したので、あくまでも参考用です。

○Cコンパイラ環境
  C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0配下
  ○開発環境:「mingw-w64.bat」を実行してcmdを開く

○Cソース環境
  C:\Users\Public\acer\E 佳昭配下BACKUP\13.トリニタス社仕事\clang

○コンパイルと実行
  ・コンパイル1: gcc -o cert cert.c; 実行1: cert.exe
  ・コンパイル2: gcc cert.c; 実行2: a.exe

○Cヘッダー
  ・JPKICSP_ex.H
  ・JPKIServiceAPI.h

○Cソース
  iccard.c:ICカード判別機能
  cert.c:

アプリケーションのJavaソースコード

上記で紹介したJavaアプリケーションのコードを示します。
個々のアプリケーションのコンパイル/実行方法もコメントで記しています。
コンパイル方法(/* ・コンパイル)/実行方法(/* ・実行)もコメントで記しています。

◯IcCardType.java:ICカード判別機能

import jp.go.jpki.appli.JPKICardType;
import jp.go.jpki.appli.JPKIUserCertService;
import jp.go.jpki.appli.JPKIUserCertException;
import jp.go.jpki.appli.JPKIUserCertBasicData;
import jp.go.jpki.appli.JPKICryptAuthJNI;
import jp.go.jpki.appli.JPKICryptAuthJNIException;



public class Riyousya {
    public static void main(String[] args){
        System.out.println("クラスRiyousya 開始!!");

    byte pcert[] = new byte[1000];;

    try{

        JPKICryptAuthJNI jpkiCryptAuth = new JPKICryptAuthJNI();
        long hProv = jpkiCryptAuth.cryptAcquireContext(0);
        byte cert[]  = jpkiCryptAuth.cryptGetRootCertificateValue(hProv);
        System.out.println("cert長=" + cert.length);

        long hCert = jpkiCryptAuth.certCreateCertificateContext(cert);

        pcert = jpkiCryptAuth.certGetPublicKeyInfo(hCert);
        System.out.println("pcert長=" + pcert.length);

    }
    catch(Exception e){
        // その他のException発生時の処理
        System.out.println("その他1のException 発生しました");
        e.printStackTrace();

    }



System.exit(0);

/*  JPKIUserCertService ucs = new JPKIUserCertService(pcert); */
    JPKIUserCertService ucs = new JPKIUserCertService();

    JPKIUserCertBasicData res;
    try{

        res = ucs.getBasicData();

    }
    catch(Exception e){
    // その他のException発生時の処理
    System.out.println("その他2のException 発生しました");
    e.printStackTrace();

    }


    System.exit(0);

    ucs = new JPKIUserCertService();
    try{
        // ICカード種別取得
        JPKICardType cardType = ucs.getCardType();
        // 結果の取得
        int id = cardType.getID();
        if (id == JPKICardType.JPKI_CARD_ID_JYUKI) {
            // 住基カードの場合
            System.out.println("住基カードです");

        }
        else if (id == JPKICardType.JPKI_CARD_ID_BANGO) {
            // 個人番号カードの場合
            System.out.println("個人番号カードです");
/*            JPKIUserCertBasicData res = ucs.getBasicData(pcert); */
            res = ucs.getBasicData();

            System.out.println("JPKIUserCertBasicData res = ucs.getBasicData(); OK");

            String address = res.getAddress();
            System.out.println("JString address = res.getAddress(); OK");

            String bdate = res.getDateOfBirth();
            String gender = res.getGender();
            String name = res.getName();
            System.out.println("address="+address);
            System.out.println("bdate="+bdate);
            System.out.println("gender="+gender);
            System.out.println("name="+name);

        }
        else if (id == JPKICardType.JPKI_CARD_ID_UNKNOWN) {
            // 不明の場合
            System.out.println("不明なカードです");
        }
    }
    catch(JPKIUserCertException e){
        // JPKIUserCertException 発生時の処理
        System.out.println("JPKIUserCertException 発生しました");
        e.printStackTrace();
    }
    catch(Exception e){
        // その他のException発生時の処理
        System.out.println("その他のException 発生しました");
        e.printStackTrace();

    }
 


    }
}

◯CryptAuth.java:利用者電子証明書の機能

import jp.go.jpki.appli.JPKICryptAuthJNI;
import jp.go.jpki.appli.JPKICryptAuthJNIException;
import jp.go.jpki.appli.JPKIUserCertService;
import jp.go.jpki.appli.JPKIUserCertException;
import jp.go.jpki.appli.JPKIUserCertBasicData;


/* ・コンパイル:
javac -classpath "%ProgramFiles%\JPKILib\Javalib64\JPKICryptAuthJNI.jar;%ProgramFiles%\JPKILib\Javalib64\JPKIUserCertService.jar" CryptAuth.java
*/
/* ・実行:
java -classpath "%ProgramFiles%\JPKILib\Javalib64\JPKICryptAuthJNI.jar;%ProgramFiles%\JPKILib\Javalib64\JPKIUserCertService.jar;./" CryptAuth
*/



public class CryptAuth {
    public static void main(String[] args){
        System.out.println("クラスCryptAuth 開始!!");

    try{
        //コンストラクタ
        JPKICryptAuthJNI jpkiCryptAuth = new JPKICryptAuthJNI();

        //(1)プロバイダハンドルを取得
        long hProv = jpkiCryptAuth.cryptAcquireContext(0);

        //(2)プロバイダの秘密鍵ハンドルを取得
        long hKey = jpkiCryptAuth.cryptGetUserKey(hProv);

        //(3)秘密鍵に対応する利用者証明書を取得
        byte[] bCert = jpkiCryptAuth.cryptGetCertificateValue(hKey);

        //(4)鍵ハンドルを解放
        jpkiCryptAuth.cryptDestroyKey(hKey);

        //(5)プロバイダハンドルを解放
        jpkiCryptAuth.cryptReleaseContext(hProv);

        System.out.println("証明書の長さ=" + bCert.length);

        //基本4情報を取得する
        JPKIUserCertService ucs = new JPKIUserCertService(bCert);

        try {
            //証明書を表示する
            ucs.showCertViewer();
        } catch (JPKIUserCertException e) {
            // JPKIUserCertException 発生時の処理
            int code = e.getErrorCode();
            String str_code = Integer.valueOf(code).toString();
            System.out.println("JPKIUserCertException 発生しました エラーコード=" + str_code);
                    e.printStackTrace();

        } catch (Exception e) {
        // その他のException発生時の処理
            System.out.println("その他のException発生 発生しました");
            e.printStackTrace();
        }

        // 基本4情報取得機能
            JPKIUserCertBasicData bd = ucs.getBasicData();
            System.out.println("基本4情報:氏名:" + bd.getName());
            System.out.println("基本4情報:住所:" + bd.getAddress());
            System.out.println("基本4情報:性別:" + bd.getGender() + " ※1=男性 2=女性 3=不明");
            System.out.println("基本4情報:生年月日:" + bd.getDateOfBirth());

    } catch (JPKICryptAuthJNIException e) {
 
        // 機能特有の例外
        switch (e.getErrorCode()) {
        case JPKICryptAuthJNIException.JPKI_ERR_PARAM :
            //引数エラー
            System.out.println("引数エラー:JPKICryptAuthJNIException.JPKI_ERR_PARAM 発生しました");
            e.printStackTrace();

            break;
        case JPKICryptAuthJNIException.JPKI_ERR_WINDOWS :
            //Windowsエラー
            switch (e.getWinErrorCode()) {
                case JPKICryptAuthJNIException.JPKI_WIN_ERR_NO_MEMORY :
                    System.out.println("Windowsエラー:JPKICryptAuthJNIException.JPKI_WIN_ERR_NO_MEMORY 発生しました");
                    e.printStackTrace();
                break;
            // その他処理するエラーコードを記述
                default :
                // 予期しないWindowsエラー
                    System.out.println("予期しないWindowsエラー:JPKICryptAuthJNIException 発生しました");
                    e.printStackTrace();

                break;

            //基本4情報を表示する
            
         }
      } 

    } catch (Exception e) {
    // その他の例外
    }
    System.out.println("クラスCryptAuth 終了!!");

  }
}


◯CryptAuthValidate.java:利用者電子証明書の検証

import jp.go.jpki.appli.JPKICryptAuthJNI;
import jp.go.jpki.appli.JPKICryptAuthJNIException;
import jp.go.jpki.appli.JPKIUserCertService;
import jp.go.jpki.appli.JPKIUserCertException;
import jp.go.jpki.appli.JPKIUserCertBasicData;
import jp.go.jpki.appli.JPKIConfirmResult;


/* ・コンパイル:
javac -classpath "%ProgramFiles%\JPKILib\Javalib64\JPKICryptAuthJNI.jar;%ProgramFiles%\JPKILib\Javalib64\JPKIUserCertService.jar" CryptAuthValidate.java
*/
/* ・実行:
java -classpath "%ProgramFiles%\JPKILib\Javalib64\JPKICryptAuthJNI.jar;%ProgramFiles%\JPKILib\Javalib64\JPKIUserCertService.jar;./" CryptAuthValidate
*/



public class CryptAuthValidate {
    public static void main(String[] args){
        System.out.println("クラスCryptAuthValidate 開始!!");

/* JPKIUserCertService ucs; */
byte[] bCert = new byte[1000];

    try{
        //コンストラクタ
        JPKICryptAuthJNI jpkiCryptAuth = new JPKICryptAuthJNI();

        //(1)プロバイダハンドルを取得
        long hProv = jpkiCryptAuth.cryptAcquireContext(0);

        //(2)プロバイダの秘密鍵ハンドルを取得
        long hKey = jpkiCryptAuth.cryptGetUserKey(hProv);

        //(3)秘密鍵に対応する利用者証明書を取得
        bCert = jpkiCryptAuth.cryptGetCertificateValue(hKey);

        //(4)鍵ハンドルを解放
        jpkiCryptAuth.cryptDestroyKey(hKey);

        //(5)プロバイダハンドルを解放
        jpkiCryptAuth.cryptReleaseContext(hProv);

        System.out.println("証明書の長さ=" + bCert.length);


    }
    catch(Exception e){
        // その他のException発生時の処理
    }

   //基本4情報を取得する
   JPKIUserCertService ucs = new JPKIUserCertService(bCert);

    try{
        // 有効性確認
        JPKIConfirmResult res = ucs.confirm();
        // 結果の取得
        int code = res.getCode();
        // 結果メッセージの取得
        String msg = res.getMessage();
        // 結果コードの従った処理
        switch (code) {
            // 有効
            case JPKIConfirmResult.JPKI_CONFIRM_OK:
                System.out.println("利用者電子証明書の有効性を確認しました");
                break;
            // 無効 (有効期限切れ)
            case JPKIConfirmResult.JPKI_CLIENT_EXPIRED_ERROR:
                System.out.println("利用者証明書が無効:有効期限切れ");
            // 無効 (失効済)
            case JPKIConfirmResult.JPKI_SERVER_REVOKED_ERROR:
                System.out.println("利用者証明書が無効:失効済");
            // 無効 (失効申請中)
            case JPKIConfirmResult.JPKI_SERVER_APPLYED_ERROR:
                System.out.println("利用者証明書が無効:失効申請中");
            // 無効(一時保留)
            case JPKIConfirmResult.JPKI_SERVER_HOLD_ERROR:
                System.out.println("利用者証明書が無効:一時保留");
                // 無効の場合の処理
                break;
            // 有効性確認失敗
            default :
                // 有効性確認中に発生したExceptionの取得 
                Exception ex = res.getException();
                System.out.println("有効性以外の、その他の例外が発生しました");

                // サーバ要因エラー,HTTP通信エラー
                if(ex == null){
                    // ・サーバ要因エラー(JPKIConfirmResultフィールド値:600番台)
                    // ・HTTP通信エラー  (HTTPステータスコード:100~500番台)
                    // の場合の処理
 
                // クライアント要因エラー
                }else{

/*
                    switch(ex){
                        // JPKIUserCertExceptionの場合
                        case JPKIUserCertException:
                            // エラーコード取得
                            code = ex.getErrorCode();
                            break;
                        // JPKICryptJNIExceptionの場合
                        case JPKICryptJNIException:
                            // エラーコード取得
                            code = ex.getErrorCode();
                            int wincode = ex.getwinErrorCode();
                            break;
                        // Java標準Exceptionの場合
                        case Exception:
                            // Java標準Exceptionの場合の処理
                            break;
                        // 上記以外の例外の場合
                        default:
                            // 処理
                            break;
                    }
*/
                }
                break;
        }
    }
    catch(JPKIUserCertException e){
        // JPKIUserCertException 発生時の処理
    }
    catch(Exception e){
        // その他のException発生時の処理
    }

    System.out.println("クラスCryptAuthValidate 終了!!");

  }
}


◯CryptSign.java:署名用電子証明書の機能

import jp.go.jpki.appli.JPKICryptSignJNI;
import jp.go.jpki.appli.JPKICryptSignJNIException;
import jp.go.jpki.appli.JPKIUserCertService;
import jp.go.jpki.appli.JPKIUserCertException;
import jp.go.jpki.appli.JPKIUserCertBasicData;


/* ・コンパイル:
javac -classpath "%ProgramFiles%\JPKILib\Javalib64\JPKICryptSignJNI.jar;%ProgramFiles%\JPKILib\Javalib64\JPKIUserCertService.jar" CryptSign.java
*/
/* ・実行:
java -classpath "%ProgramFiles%\JPKILib\Javalib64\JPKICryptSignJNI.jar;%ProgramFiles%\JPKILib\Javalib64\JPKIUserCertService.jar;./" CryptSign
*/



public class CryptSign {
    public static void main(String[] args){
        System.out.println("クラスSign 開始!!");

    try{
        //コンストラクタ
        JPKICryptSignJNI jpkiCryptSign = new JPKICryptSignJNI();

        //(1)プロバイダハンドルを取得
        long hProv = jpkiCryptSign.cryptAcquireContext(0);

        //(2)プロバイダの秘密鍵ハンドルを取得
        long hKey = jpkiCryptSign.cryptGetUserKey(hProv);

        //(3)秘密鍵に対応する署名証明書を取得
        byte[] bCert = jpkiCryptSign.cryptGetCertificateValue(hKey);

        //(4)鍵ハンドルを解放
        jpkiCryptSign.cryptDestroyKey(hKey);

        //(5)プロバイダハンドルを解放
        jpkiCryptSign.cryptReleaseContext(hProv);

        System.out.println("証明書の長さ=" + bCert.length);

        //基本4情報を取得する
        JPKIUserCertService ucs = new JPKIUserCertService(bCert);

        try {
            //証明書を表示する
            ucs.showCertViewer();
        } catch (JPKIUserCertException e) {
            // JPKIUserCertException 発生時の処理
            int code = e.getErrorCode();
            String str_code = Integer.valueOf(code).toString();
            System.out.println("JPKIUserCertException 発生しました エラーコード=" + str_code);
                    e.printStackTrace();

        } catch (Exception e) {
        // その他のException発生時の処理
            System.out.println("その他のException発生 発生しました");
            e.printStackTrace();
        }

        // 基本4情報取得機能
            JPKIUserCertBasicData bd = ucs.getBasicData();
            System.out.println("基本4情報:氏名:" + bd.getName());
            System.out.println("基本4情報:住所:" + bd.getAddress());
            System.out.println("基本4情報:性別:" + bd.getGender() + " ※1=男性 2=女性 3=不明");
            System.out.println("基本4情報:生年月日:" + bd.getDateOfBirth());

    } catch (JPKICryptSignJNIException e) {
 
        // 機能特有の例外
        switch (e.getErrorCode()) {
        case JPKICryptSignJNIException.JPKI_ERR_PARAM :
            //引数エラー
            System.out.println("引数エラー:JPKICryptSignJNIException.JPKI_ERR_PARAM 発生しました");
            e.printStackTrace();

            break;
        case JPKICryptSignJNIException.JPKI_ERR_WINDOWS :
            //Windowsエラー
            switch (e.getWinErrorCode()) {
                case JPKICryptSignJNIException.JPKI_WIN_ERR_NO_MEMORY :
                    System.out.println("Windowsエラー:JPKICryptSignJNIException.JPKI_WIN_ERR_NO_MEMORY 発生しました");
                    e.printStackTrace();
                break;
            // その他処理するエラーコードを記述
                default :
                // 予期しないWindowsエラー
                    System.out.println("予期しないWindowsエラー:JPKICryptSignJNIException 発生しました");
                    e.printStackTrace();

                break;
            
         }
      } 

    } catch (Exception e) {
    // その他の例外
    }
    System.out.println("クラスSign 終了!!");

  }
}



◯CryptSignValidate.java:署名用電子証明書の検証

import jp.go.jpki.appli.JPKICryptSignJNI;
import jp.go.jpki.appli.JPKICryptSignJNIException;
import jp.go.jpki.appli.JPKIUserCertService;
import jp.go.jpki.appli.JPKIUserCertException;
import jp.go.jpki.appli.JPKIUserCertBasicData;
import jp.go.jpki.appli.JPKIConfirmResult;


/* ・コンパイル:
javac -classpath "%ProgramFiles%\JPKILib\Javalib64\JPKICryptSignJNI.jar;%ProgramFiles%\JPKILib\Javalib64\JPKIUserCertService.jar" CryptSignValidate.java
*/
/* ・実行:
java -classpath "%ProgramFiles%\JPKILib\Javalib64\JPKICryptSignJNI.jar;%ProgramFiles%\JPKILib\Javalib64\JPKIUserCertService.jar;./" CryptSignValidate
*/



public class CryptSignValidate {
    public static void main(String[] args){
        System.out.println("クラスCryptSignValidate 開始!!");

/* JPKIUserCertService ucs; */
byte[] bCert = new byte[1000];

    try{
        //コンストラクタ
        JPKICryptSignJNI jpkiCryptSign = new JPKICryptSignJNI();

        //(1)プロバイダハンドルを取得
        long hProv = jpkiCryptSign.cryptAcquireContext(0);

        //(2)プロバイダの秘密鍵ハンドルを取得
        long hKey = jpkiCryptSign.cryptGetUserKey(hProv);

        //(3)秘密鍵に対応する利用者証明書を取得
        bCert = jpkiCryptSign.cryptGetCertificateValue(hKey);

        //(4)鍵ハンドルを解放
        jpkiCryptSign.cryptDestroyKey(hKey);

        //(5)プロバイダハンドルを解放
        jpkiCryptSign.cryptReleaseContext(hProv);

        System.out.println("証明書の長さ=" + bCert.length);


    }
    catch(Exception e){
        // その他のException発生時の処理
    }

   //基本4情報を取得する
   JPKIUserCertService ucs = new JPKIUserCertService(bCert);

    try{
        // 有効性確認
        JPKIConfirmResult res = ucs.confirm();
        // 結果の取得
        int code = res.getCode();
        // 結果メッセージの取得
        String msg = res.getMessage();
        // 結果コードの従った処理
        switch (code) {
            // 有効
            case JPKIConfirmResult.JPKI_CONFIRM_OK:
                System.out.println("署名用電子証明書の有効性を確認しました");
                break;
            // 無効 (有効期限切れ)
            case JPKIConfirmResult.JPKI_CLIENT_EXPIRED_ERROR:
                System.out.println("署名用証明書が無効:有効期限切れ");
            // 無効 (失効済)
            case JPKIConfirmResult.JPKI_SERVER_REVOKED_ERROR:
                System.out.println("署名用証明書が無効:失効済");
            // 無効 (失効申請中)
            case JPKIConfirmResult.JPKI_SERVER_APPLYED_ERROR:
                System.out.println("署名用証明書が無効:失効申請中");
            // 無効(一時保留)
            case JPKIConfirmResult.JPKI_SERVER_HOLD_ERROR:
                System.out.println("署名用証明書が無効:一時保留");
                // 無効の場合の処理
                break;
            // 有効性確認失敗
            default :
                // 有効性確認中に発生したExceptionの取得 
                Exception ex = res.getException();
                System.out.println("有効性以外の、その他の例外が発生しました");
                // サーバ要因エラー,HTTP通信エラー
                if(ex == null){
                    // ・サーバ要因エラー(JPKIConfirmResultフィールド値:600番台)
                    // ・HTTP通信エラー  (HTTPステータスコード:100~500番台)
                    // の場合の処理
 
                // クライアント要因エラー
                }else{
/*
                    switch(ex){
                        // JPKIUserCertExceptionの場合
                        case JPKIUserCertException:
                            // エラーコード取得
                            code = ex.getErrorCode();
                            break;
                        // JPKICryptJNIExceptionの場合
                        case JPKICryptJNIException:
                            // エラーコード取得
                            code = ex.getErrorCode();
                            int wincode = ex.getwinErrorCode();
                            break;
                        // Java標準Exceptionの場合
                        case Exception:
                            // Java標準Exceptionの場合の処理
                            break;
                        // 上記以外の例外の場合
                        default:
                            // 処理
                            break;
                    }
*/
                }
                break;
        }
    }
    catch(JPKIUserCertException e){
        // JPKIUserCertException 発生時の処理
    }
    catch(Exception e){
        // その他のException発生時の処理
    }

    System.out.println("クラスCryptSignValidate 終了!!");

  }
}



 

著者:志村佳昭(株式会社トリニタス 技術顧問)