Поставщик 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", поэтому у меня не может быть одного провайдера на одну смарт-карту.

Это случается также с кем-то еще? Любое решение?

2 ответа

Решение

Я заметил, глядя на 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, (В настоящее время я не могу проверить это).

Однако я нигде не могу найти этот факт публично задокументированным, поэтому он может быть изменен, а также работать по-разному для разных поставщиков, то есть использовать на свой страх и риск!,

Проблема в том, что в списке может быть загружен только один провайдер PKCS#11.

Решение вашей проблемы, кажется, определено в самой документации, связанной с.

Чтобы использовать более одного слота на PKCS#11 реализация, или использовать более одного PKCS#11 реализации, просто повторите установку для каждого с соответствующим файлом конфигурации. Это приведет к созданию экземпляра поставщика Sun PKCS#11 для каждого слота каждого PKCS#11 реализация.

Пример конфигурации в следующем формате attribute=value было бы:

name = FooAccelerator
library = /opt/foo/lib/libpkcs11.so
slot = 1

Кроме того, вы можете использовать атрибуты в файле конфигурации провайдера PKCS#11 в той же ссылке, чтобы сконфигурировать более одного провайдера с разными слотами Id и listIndex и разными атрибутами.

Другие вопросы по тегам