Поставщик 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 и разными атрибутами.