Поставщик SunPKCS11 в Java 9
До Java 8 поставщик SunPKCS11 был загружен следующим образом:
Provider provider = new sun.security.pkcs11.SunPKCS11 (new ByteArrayInputStream (configFile.getBytes ());
Security.addProvider (provider);
"configFile" - это строка с параметрами конфигурации. Таким образом, если приложение должно работать с несколькими подключенными смарт-картами, оно может создавать несколько поставщиков. Для доступа к каждому провайдеру было использовано имя "SunPKCS11-", за которым следует имя, указанное в конфигурации.
В Java 8 класс sun.security.pkcs11.SunPKCS11
был удален в JDK. Итак, мне пришлось запрограммировать предыдущий вызов путем отражения.
Работа провайдера PKCS # 11 в Java 9 кажется совсем другой:
-
Конструктор SunPKCS11 был изменен на пустой. Конфигурация загружается методом "configure", поэтому обязательно, что она находится в файле на диске, и я больше не могу загружать ее через поток в строку.
-
Если мы попытаемся использовать отражение, появятся следующие предупреждения:
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by PruebaTarjeta (file:/C:/temp/pkcs11java9/classes/) to constructor
sun.security.pkcs11.SunPKCS11()
WARNING: Please consider reporting this to the maintainers of PruebaTarjeta
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
- В Java 9 поставщик SunPKCS11 автоматически создается и входит в список поставщиков криптографии. Его можно получить из списка и настроить. Проблема в том, что в список может быть только один поставщик PKCS # 11. Документация Java 9 указывает, что мы можем получить провайдера PKCS # 11 с "SunPKCS11-", за которым следует имя, указанное в конфигурации, но оно не правда. Если мы посмотрим на список поставщиков, то единственным является "SunPKCS11", поэтому у меня не может быть одного поставщика на смарт-карту.
Случалось ли это с кем-то еще? Любое решение?
Ответы
Ответ 1
Я заметил, глядя на javadoc для configure
:
Примените прилагаемый аргумент конфигурации к этому экземпляру поставщика и верните настроенный провайдер. Обратите внимание, что если этот провайдер не может быть настроен на месте, будет создан и возвращен новый поставщик. Поэтому вызывающие абоненты должны всегда использовать возвращаемого поставщика.
Это указывает на то, что здесь используется прототип , и что новый поток управления для создания нескольких поставщиков будет чем-то вроде
Provider prototype = Security.getProvider("SunPKCS11");
Provider provider1 = prototype.configure(...);
Provider provider2 = prototype.configure(...);
...
Что касается использования аргументов напрямую, а не имени файла, я немного искал исходный код и нашел это в sun.security.pkcs11.Config
:
Config(String fn) throws IOException {
this.filename = fn;
if (filename.startsWith("--")) {
// inline config
String config = filename.substring(2).replace("\\n", "\n");
reader = new StringReader(config);
Обратите внимание на строку с filename.startsWith("--")
, это имя файла поступает непосредственно из аргумента в configure
. Таким образом, вы должны иметь возможность передавать аргументы конфигурации в виде строки, пока вы начинаете строку с --
, а затем разделите пары key=value
на \n
. (В настоящее время я не могу это проверить).
Однако я не могу найти этот факт публично документированным в любом месте, поэтому он может быть изменен, а также он будет работать по-разному для разных поставщиков, т.е. использовать на свой страх и риск!.
Ответ 2
Проблема заключается в том, что у вас может быть только один поставщик PKCS # 11, загруженный в список.
Решение проблемы, как представляется, определено в doc, связанное непосредственно.
Чтобы использовать более одного слота на реализацию PKCS#11
или использовать более одной реализации PKCS#11
, просто повторите установку для каждого с соответствующим конфигурационным файлом. Это приведет к экземпляру поставщика Sun PKCS # 11 для каждого слота в каждой реализации PKCS#11
.
Пример конфигурации в формате attribute=value
будет:
name = FooAccelerator
library = /opt/foo/lib/libpkcs11.so
slot = 1
Вы также можете использовать атрибуты в конфигурационном файле поставщика PKCS # 11 в той же ссылке, чтобы настроить несколько поставщиков с разными идентификаторами слотов и listIndex и разными атрибутами.