分析に役立つ可能性のある背景情報:
Web アプリケーションからスマート カードに接続し、クライアント マシンで実行されている Java プログラムから証明書を読み取って署名操作を実行しようとしています。Opensc-PKCS11.dll を java sunpkcs11 プロバイダー クラスと共に使用して、スマート カード (FIPS PIV 準拠のスマート カード) の証明書にアクセスしています。
私の問題は、スマート カードが接続されている限り、スマート カードのキーストアにアクセスして暗号化操作を実行できることですが、スマート カードを取り外して再度挿入すると、プロバイダのロードが失敗するために、プログラムがスロット ID を取得できません。
スロット ID をハードコーディングできないため、0/-1 のままにしておきます
Config file content
Name="Opensc"
Library="OpenSC-PKCS11.dll"
slot=-1
showinfo=true
byte[] pkcs11configBytes = configName.getBytes();
ByteArrayInputStream confStream = new ByteArrayInputStream(pkcs11configBytes);
bc = new org.bouncycastle.jce.provider.BouncyCastleProvider();
Security.addProvider(bc);
sun = new sun.security.pkcs11.SunPKCS11(confStream);
Security.addProvider(sun);
この質問は関連していますが、十分な情報を提供します。 Java - スマートカードのホットプラグを検出する方法
更新: 問題を修正できました。最終ブロックでは、プロバイダーでのジョブが終了した後、プロバイダーから C_Finalize を呼び出しました。同じJavaインスタンスでの次の実行のために、PKCS11マップをクリアしてプロバイダーを再度初期化する以下のようなことを行いました
Field moduleMapField = PKCS11.class.getDeclaredField("moduleMap");
moduleMapField.setAccessible(true);
Map<?, ?> moduleMap = (Map<?, ?>) moduleMapField.get(null);
moduleMap.clear(); // force re-execution of C_Initialize next time
//load PKCS#11
Method getInstanceMethod = PKCS11.class.getMethod("getInstance",
String.class, String.class, CK_C_INITIALIZE_ARGS.class,
Boolean.TYPE);
CK_C_INITIALIZE_ARGS ck_c_initialize_args = new CK_C_INITIALIZE_ARGS();
pkcs11 = (PKCS11) getInstanceMethod.invoke(null, libFile,
"C_GetFunctionList", ck_c_initialize_args, false);