Проблема обнаружения слотов java pkcs11 с OpenSC, если смарт-карта удалена и вставлена снова
Справочная информация, которая может помочь в анализе:
Из веб-приложения я пытаюсь подключиться к смарт-карте и прочитать сертификаты из Java-программы, которая запускается на клиентском компьютере для выполнения какой-либо операции подписи. Я использую Opensc-PKCS11.dll с классом поставщика java sunpkcs11 для доступа к сертификату на смарт-карте (смарт-карта соответствия FIPS PIV).
Моя проблема в том, что, когда смарт-карта подключена, я могу получить доступ к хранилищу ключей на смарт-карте и выполнять криптографические операции, но когда мы извлекаем смарт-карту и вставляем ее снова, программа не может получить идентификатор слота из-за сбоя загрузки провайдера.
Так как я не могу жестко закодировать свой идентификатор слота, я оставляю его как 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 - как обнаружить смарт-карту
Обновление: я мог решить проблему. В блоке finally я вызвал 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);