pkcs11.txtファイルとは?PKCS#11の設定ファイルを徹底解説

Javaでセキュリティ関連のプログラムを開発していると、「pkcs11.txt」や「pkcs11.cfg」といったファイル名を見かけることがあります。これは一体何のファイルで、どう設定すればいいのでしょうか?

今回は、PKCS#11の設定ファイル(pkcs11.txtやpkcs11.cfg)について、基礎から実践的な使い方まで詳しく解説します。

スポンサーリンク
  1. PKCS#11とは?基礎知識をおさらい
    1. PKCS#11の定義
    2. PKCS#11が使われる場面
    3. なぜPKCS#11が必要なのか?
  2. pkcs11.txtファイルとは?役割と位置づけ
    1. pkcs11.txtの正体
    2. pkcs11.txtファイルの役割
  3. pkcs11.txtファイルの基本的な書き方
    1. 最小限の設定例
    2. Windowsでの設定例
    3. Linuxでの設定例
    4. スマートカード(マイナンバーカード)の設定例
  4. pkcs11.txtの詳細設定項目
    1. 主要な設定項目一覧
  5. Javaでのpkcs11.txtファイルの使い方
    1. 静的なプロバイダー登録(java.securityファイルに記述)
    2. 動的なプロバイダー登録(プログラムから読み込み)
    3. 設定を文字列で直接指定する方法
  6. KeyStoreとしてPKCS#11トークンを使う
    1. KeyStoreの取得とログイン
    2. システムプロパティで設定する方法
  7. keytoolでPKCS#11トークンを操作する
    1. KeyStoreの内容を一覧表示
    2. 特定のプロバイダーを指定する
    3. 証明書をエクスポート
  8. よくある設定例とトラブルシューティング
    1. 例1:OpenSCを使ったスマートカード設定
    2. 例2:SoftHSMを使った開発環境設定
    3. 例3:Windows環境でのスマートカード設定
    4. トラブル1:「ライブラリが見つからない」エラー
    5. トラブル2:「スロットが見つからない」エラー
    6. トラブル3:「PINが間違っている」エラー
    7. デバッグ用設定
  9. 実践例:マイナンバーカードでの電子署名
    1. pkcs11.txtの設定
    2. Javaコードの例(概要)
  10. まとめ:pkcs11.txtファイルの重要ポイント

PKCS#11とは?基礎知識をおさらい

まず、pkcs11.txtファイルを理解するために、PKCS#11そのものについて簡単に説明します。

PKCS#11の定義

PKCS#11(Public-Key Cryptography Standards #11)とは、暗号化デバイスとアプリケーションの間のインターフェースを定義する標準規格です。別名「Cryptoki」(クリプトキー)とも呼ばれます。

簡単に言うと:

PKCS#11は、スマートカードやハードウェアセキュリティモジュール(HSM)などの暗号化デバイスを、プログラムから統一的な方法で使えるようにするための「共通言語」のようなものです。

PKCS#11が使われる場面

主な用途:

  • スマートカード:公的個人認証(マイナンバーカード)、社員証など
  • ハードウェアセキュリティモジュール(HSM):銀行や企業のサーバーで使用
  • USBトークン:暗号鍵を保存する物理デバイス
  • 暗号化アクセラレータ:暗号化処理を高速化するハードウェア

なぜPKCS#11が必要なのか?

通常、暗号化デバイスはメーカーごとに独自のドライバーやAPIを持っています。PKCS#11という標準規格があることで、開発者は特定のデバイスに依存せず、統一されたAPIでプログラムを書けるのです。

pkcs11.txtファイルとは?役割と位置づけ

pkcs11.txtの正体

pkcs11.txt(またはpkcs11.cfg)は、PKCS#11プロバイダーを設定するためのテキスト形式の設定ファイルです。

ファイル名について:

  • 拡張子は「.txt」「.cfg」のどちらでもOK
  • ファイル名も「pkcs11.txt」「pkcs11.cfg」など任意
  • 重要なのは中身の書き方

この設定ファイルは、主にJavaのセキュリティプロバイダー(SunPKCS11)を設定する際に使用されます。

pkcs11.txtファイルの役割

設定ファイルには、以下の情報を記述します:

  1. どのPKCS#11ライブラリを使うか(dllファイルやsoファイルのパス)
  2. プロバイダーの名前
  3. 使用するスロット番号(デバイスの番号)
  4. その他の詳細設定

pkcs11.txtファイルの基本的な書き方

最小限の設定例

最もシンプルなpkcs11.txtファイルの例を見てみましょう。

name = MyToken
library = /opt/pkcs11/lib/libpkcs11.so

各項目の説明:

  • name:このプロバイダーの名前(必須)
  • library:PKCS#11ライブラリのフルパス(必須)

Windowsでの設定例

name = SmartCard
library = C:\Windows\System32\smartcard.dll

注意点:

  • Windowsの場合、パスの区切り文字は「\」(バックスラッシュ)
  • フルパス(絶対パス)で指定する必要があります

Linuxでの設定例

name = HSM
library = /usr/lib/libpkcs11.so
slot = 0

slot:複数のトークンがある場合、どのスロットを使うか指定します。

スマートカード(マイナンバーカード)の設定例

name = JPKI
library = /usr/local/lib/libjpki.so
description = 公的個人認証サービス

日本の公的個人認証サービス(マイナンバーカード)を使う場合の例です。

pkcs11.txtの詳細設定項目

基本項目以外にも、さまざまな設定が可能です。

主要な設定項目一覧

name(必須)

プロバイダーの名前を指定します。

name = MyProvider

このプロバイダーは「SunPKCS11-MyProvider」という名前でJavaから参照されます。

library(必須)

PKCS#11ライブラリのファイルパスを指定します。

library = /opt/lib/libpkcs11.so

重要: セキュリティ上の理由から、必ず絶対パスで指定してください。相対パスは使用できません。

slot

使用するスロット番号を指定します(オプション)。

slot = 0

slotListIndex

複数のスロットがある場合、リストのインデックスを指定します。

slotListIndex = 1

description

プロバイダーの説明を記述します(オプション)。

description = Hardware Security Module Provider

enabledMechanisms

使用する暗号化メカニズムを限定します。

enabledMechanisms = {
  CKM_RSA_PKCS
  CKM_SHA256_RSA_PKCS
}

disabledMechanisms

使用しない暗号化メカニズムを指定します。

disabledMechanisms = {
  CKM_DES_ECB
}

attributes

オブジェクト作成時に設定する追加属性を指定します。

attributes = {
  CKO_CERTIFICATE = {
    CKA_TOKEN = true
  }
}

showInfo

デバッグ情報を表示するかどうか(trueまたはfalse)。

showInfo = true

これを有効にすると、ライブラリ、スロット、トークン、メカニズムの情報が表示されます。

Javaでのpkcs11.txtファイルの使い方

実際にJavaプログラムでpkcs11.txtを使う方法を見ていきましょう。

静的なプロバイダー登録(java.securityファイルに記述)

手順1:pkcs11.txtファイルを作成

name = MyToken
library = /opt/lib/libpkcs11.so

このファイルを /opt/config/pkcs11.txt として保存します。

手順2:java.securityファイルを編集

$JAVA_HOME/conf/security/java.security(または$JAVA_HOME/lib/security/java.security)を開き、以下を追加します。

security.provider.13=SunPKCS11 /opt/config/pkcs11.txt

注意: 番号(この例では13)は、既存のプロバイダーの次の番号を指定します。

動的なプロバイダー登録(プログラムから読み込み)

Javaコードから直接設定ファイルを読み込むこともできます。

Java 8以前の方法:

import java.security.Provider;
import java.security.Security;
import sun.security.pkcs11.SunPKCS11;

public class PKCS11Example {
    public static void main(String[] args) throws Exception {
        // 設定ファイルのパスを指定
        String configFile = "/opt/config/pkcs11.txt";

        // SunPKCS11プロバイダーのインスタンスを作成
        Provider provider = new SunPKCS11(configFile);

        // プロバイダーを登録
        Security.addProvider(provider);

        System.out.println("PKCS11 Provider registered: " + provider.getName());
    }
}

Java 9以降の推奨方法:

import java.security.Provider;
import java.security.Security;

public class PKCS11Example {
    public static void main(String[] args) throws Exception {
        // SunPKCS11プロバイダーを取得
        Provider baseProvider = Security.getProvider("SunPKCS11");

        // 設定ファイルで構成
        String configFile = "/opt/config/pkcs11.txt";
        Provider provider = baseProvider.configure(configFile);

        // プロバイダーを登録
        Security.addProvider(provider);

        System.out.println("PKCS11 Provider registered: " + provider.getName());
    }
}

設定を文字列で直接指定する方法

ファイルを作らず、設定内容を文字列として渡すこともできます。

import java.io.ByteArrayInputStream;
import java.security.Provider;
import java.security.Security;

public class PKCS11StringConfig {
    public static void main(String[] args) throws Exception {
        // 設定内容を文字列で定義("--"で始める)
        String config = "--name=MyToken\n" +
                        "library=/opt/lib/libpkcs11.so\n" +
                        "slot=0\n";

        // SunPKCS11プロバイダーを取得して設定
        Provider baseProvider = Security.getProvider("SunPKCS11");
        Provider provider = baseProvider.configure(config);

        // プロバイダーを登録
        Security.addProvider(provider);

        System.out.println("PKCS11 Provider registered: " + provider.getName());
    }
}

注意: 文字列で指定する場合、最初に「–」(ダブルハイフン)を付けます。

KeyStoreとしてPKCS#11トークンを使う

設定したPKCS#11プロバイダーを使って、実際に暗号鍵にアクセスしてみましょう。

KeyStoreの取得とログイン

import java.security.KeyStore;
import java.security.Provider;
import java.security.Security;

public class PKCS11KeyStoreExample {
    public static void main(String[] args) throws Exception {
        // PKCS11プロバイダーを登録
        Provider baseProvider = Security.getProvider("SunPKCS11");
        Provider provider = baseProvider.configure("/opt/config/pkcs11.txt");
        Security.addProvider(provider);

        // PKCS11のKeyStoreを取得
        KeyStore keyStore = KeyStore.getInstance("PKCS11", provider);

        // PINコードでログイン
        char[] pin = "12345678".toCharArray();
        keyStore.load(null, pin);

        // KeyStore内のエイリアス(鍵の名前)を一覧表示
        java.util.Enumeration<String> aliases = keyStore.aliases();
        while (aliases.hasMoreElements()) {
            String alias = aliases.nextElement();
            System.out.println("Alias: " + alias);
        }
    }
}

重要ポイント:

  • KeyStore.getInstance("PKCS11", provider) でPKCS11型のKeyStoreを取得
  • keyStore.load(null, pin) の第1引数はnull、第2引数がPINコード

システムプロパティで設定する方法

コマンドラインから直接設定することもできます。

java -Djavax.net.ssl.keyStoreType=PKCS11 \
     -Djavax.net.ssl.keyStore=NONE \
     -Djavax.net.ssl.keyStoreProvider=SunPKCS11-MyToken \
     MyApplication

keytoolでPKCS#11トークンを操作する

Javaに付属のkeytoolコマンドでも、PKCS#11トークンを扱えます。

KeyStoreの内容を一覧表示

keytool -keystore NONE -storetype PKCS11 -list

実行時の流れ:

  1. PINコードの入力を求められます
  2. トークン内の証明書や鍵が一覧表示されます

特定のプロバイダーを指定する

複数のPKCS11プロバイダーが登録されている場合:

keytool -keystore NONE -storetype PKCS11 \
        -providerName SunPKCS11-SmartCard \
        -list

証明書をエクスポート

keytool -keystore NONE -storetype PKCS11 \
        -exportcert -alias mycert \
        -file certificate.cer

よくある設定例とトラブルシューティング

例1:OpenSCを使ったスマートカード設定

name = OpenSC
library = /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
description = OpenSC PKCS#11 Provider

OpenSCは、多くのスマートカードに対応したオープンソースのPKCS#11実装です。

例2:SoftHSMを使った開発環境設定

name = SoftHSM
library = /usr/lib/softhsm/libsofthsm2.so
slot = 0
description = SoftHSM2 for Development

SoftHSMは、ソフトウェアで実装されたHSMで、開発・テスト用に便利です。

例3:Windows環境でのスマートカード設定

name = WindowsSmartCard
library = C:\Windows\System32\opensc-pkcs11.dll
description = Smart Card on Windows

トラブル1:「ライブラリが見つからない」エラー

エラーメッセージ:

CKR_LIBRARY_LOAD_FAILED

原因と対処法:

  1. ライブラリパスが間違っている
  • 絶対パスで正しく指定されているか確認
  1. 32bit/64bitの不一致
  • Java(JVM)が64bitなら、ライブラリも64bit版が必要
  • java -version でJavaのビット数を確認
  1. 依存ライブラリが不足
  • PKCS#11ライブラリが依存する他のライブラリがインストールされていない可能性
  • Linuxなら ldd /path/to/libpkcs11.so で依存関係を確認

トラブル2:「スロットが見つからない」エラー

原因と対処法:

  1. デバイスが接続されていない
  • スマートカードリーダーにカードが挿入されているか確認
  1. スロット番号が間違っている
  • showInfo=true を設定して利用可能なスロットを確認
  1. ドライバーが正しくインストールされていない
  • デバイスメーカーのドライバーを再インストール

トラブル3:「PINが間違っている」エラー

エラーメッセージ:

CKR_PIN_INCORRECT

原因と対処法:

  1. PINコードが間違っている
  • 正しいPINコードを入力
  • 複数回間違えるとロックされる可能性があるので注意
  1. PINの初期化が必要
  • トークンによっては、初回使用時にPINの設定が必要

デバッグ用設定

トラブルシューティング時は、詳細情報を表示する設定を追加します。

pkcs11.txtに追加:

showInfo = true

Javaの起動オプションに追加:

java -Djava.security.debug=sunpkcs11 MyApplication

または

java -Djava.security.debug=pkcs11keystore MyApplication

実践例:マイナンバーカードでの電子署名

日本の公的個人認証サービス(マイナンバーカード)を使った実践例です。

pkcs11.txtの設定

name = JPKI
library = /usr/local/lib/libjpki.so
description = 公的個人認証サービス

注意: ライブラリのパスは環境によって異なります。公的個人認証サービスのWebサイトから、対応するライブラリをダウンロードしてください。

Javaコードの例(概要)

import java.security.*;
import java.security.cert.Certificate;

public class JPKISignatureExample {
    public static void main(String[] args) throws Exception {
        // PKCS11プロバイダーの登録
        Provider provider = Security.getProvider("SunPKCS11")
                                    .configure("/opt/config/jpki.txt");
        Security.addProvider(provider);

        // KeyStoreの取得
        KeyStore keyStore = KeyStore.getInstance("PKCS11", provider);

        // 署名用PINでログイン
        char[] pin = "署名用PIN".toCharArray();
        keyStore.load(null, pin);

        // 署名用の秘密鍵を取得
        String alias = "JPKI Authentication";
        PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, pin);
        Certificate cert = keyStore.getCertificate(alias);

        // 署名の実行
        Signature signature = Signature.getInstance("SHA256withRSA", provider);
        signature.initSign(privateKey);
        signature.update("署名対象データ".getBytes("UTF-8"));
        byte[] signedData = signature.sign();

        System.out.println("署名完了");
    }
}

まとめ:pkcs11.txtファイルの重要ポイント

pkcs11.txtファイルは、Javaでハードウェアセキュリティデバイスを使うための重要な設定ファイルです。

覚えておきたいポイント:

  1. 必須項目は2つだけ
  • name:プロバイダーの名前
  • library:PKCS#11ライブラリのフルパス
  1. ファイル名は任意
  • pkcs11.txt、pkcs11.cfg、など何でもOK
  1. セキュリティのため絶対パスを使用
  • libraryは必ず絶対パスで指定
  1. 複数のデバイスを使う場合
  • それぞれに別の設定ファイルを作成
  1. デバッグにはshowInfo=trueが便利
  • トラブル時は詳細情報を表示
  1. Java 9以降はconfigure()メソッドを使う
  • Security.getProvider("SunPKCS11").configure(configFile)
  1. 32bit/64bitの一致が重要
  • JVMとPKCS#11ライブラリのビット数を合わせる

主な用途:

  • スマートカード(マイナンバーカード、社員証)
  • ハードウェアセキュリティモジュール(HSM)
  • USBトークン
  • SSL/TLS通信での証明書管理
  • 電子署名システム

pkcs11.txtファイルを正しく設定することで、Javaアプリケーションから安全に暗号化デバイスを利用できるようになります。セキュリティを重視するシステム開発には欠かせない知識ですので、ぜひマスターしてください!

コメント

タイトルとURLをコピーしました