Spec-Zone .ru
спецификации, руководства, описания, API
Содержание документации

Как Реализовать Провайдера в Архитектуре Криптографии Java


Введение

Платформа Java определяет ряд API, охватывающих главные области безопасности, включая криптографию, инфраструктуру управления открытыми ключами, аутентификацию, безопасную передачу, и управление доступом. Эти API позволяют разработчикам легко интегрировать безопасность в свой код программы. Они были разработаны вокруг следующих принципов:

  1. Независимость реализации

    Приложения не должны реализовать безопасность самостоятельно. Скорее они могут запросить службы безопасности с платформы Java. Службы безопасности реализуются в провайдерах (см. ниже), которые включаются в платформу Java через стандартный интерфейс. Приложение может положиться на многократных независимых провайдеров для функциональности безопасности.

  2. Функциональная совместимость реализации

    Провайдеры являются взаимодействующими через приложения. Определенно, приложение не связывается с определенным провайдером, и провайдер не связывается с определенным приложением.

  3. Расширяемость алгоритма

    Платформа Java включает много встроенных провайдеров, которые реализуют основной набор служб безопасности, которые широко используются сегодня. Однако, некоторые приложения могут положиться на появляющиеся стандарты, еще реализованные, или на собственных службах. Платформа Java поддерживает установку пользовательских провайдеров, которые реализуют такие службы.

Провайдер криптографических служб (провайдер) обращается к пакету (или ряд пакетов), которые предоставляют конкретную реализацию подмножества аспектов криптографии API Безопасности JDK.

java.security.Provider class инкапсулирует понятие поставщика систем обеспечения безопасности в платформе Java. Это определяет имя провайдера и перечисляет службы безопасности, которые это реализует. Многократные провайдеры могут быть сконфигурированы одновременно, и перечисляются в порядке предпочтения. Когда службу безопасности требуют, самый высокий приоритетный провайдер, который реализует ту службу, выбирается.

Рисунки 1 и 2 иллюстрируют эти опции для того, чтобы запросить реализацию обзора сообщения MD5. Оба данных показывают трех провайдеров что алгоритмы обзора сообщения реализации. Провайдеры упорядочиваются предпочтением слева направо (1-3). В рисунке 1 приложение запрашивает реализацию алгоритма MD5, не определяя имя провайдера. Провайдеры ищутся в привилегированном порядке и реализации от первого провайдера, предоставляющего, что определенный алгоритм, ProviderB, возвращается. В рисунке 2 приложение запрашивает реализацию алгоритма MD5 от определенного провайдера, ProviderC. На сей раз реализация от того провайдера возвращается, даже при том, что провайдер с более высоким привилегированным порядком, ProviderB, также предоставляет реализацию MD5.

Рисунки 1 и 2: Опции для того, чтобы запросить MD5 передают реализацию обзора

Рисунок 1 (уехал): поиск Провайдера. Рисунок 2 (право): Определенного провайдера требуют

У каждой установки есть один или более установленных пакетов провайдера. Клиенты могут сконфигурировать свои времена выполнения с различными провайдерами, и определить привилегированный порядок на каждого из них. Привилегированный порядок является порядком, в котором провайдеры ищутся требуемые алгоритмы, когда никакого определенного провайдера не требуют.

Версия Sun среды выполнения Java прибывает стандарт с провайдером значения по умолчанию, названным "SUN". Другие среды выполнения Java, возможно, не обязательно предоставляют провайдера "SUN".

Кто Должен Считать Этот Документ

Программисты, которые только должны использовать API Безопасности Java, чтобы получить доступ к существующим алгоритмам криптографии и другим службам, не должны считать этот документ.

Этот документ предназначается для опытных программистов, желающих создать их собственные пакеты провайдера, предоставляющие реализации криптографической службы. Это документирует то, что Вы должны сделать, чтобы интегрировать Вашего провайдера в Java так, чтобы Ваши алгоритмы и другие службы могли быть найдены, когда клиенты API Безопасности Java запрашивают их.

Связанная Документация

Этот документ предполагает, что Вы уже считали Справочник Архитектуры Криптографии Java.

Это документирует пакеты, которые содержат различные классы и интерфейсы в API Безопасности.

Примечания по Терминологии

Всюду по этому документу срокам JCA отдельно обращается к платформе JCA. Всякий раз, когда этот документ отмечает определенного провайдера JCA, он будет упомянут явно именем провайдера.

Классы механизма и Соответствующие Классы Интерфейса Поставщика услуг

Механизм class определяет криптографическую службу абстрактным способом (без конкретной реализации).

Криптографическая служба всегда связывается с определенным алгоритмом или типом. Это или обеспечивает криптографические операции (как те для цифровых подписей или обзоров сообщения, шифров или протоколов согласования ключей); генерирует или предоставляет криптографический материал (ключи или параметры) требуемый для криптографических операций; или генерирует объекты данных (keystores или сертификаты), которые инкапсулируют криптографические ключи (который может использоваться в криптографической работе) безопасным способом.

Например, вот четыре класса механизма:

Архитектура Криптографии Java охватывает классы, включающие Пакет защиты, которые касаются криптографии, включая классы механизма. Пользователи API запрашивают и используют экземпляры классов механизма, чтобы выполнить соответствующие операции. JDK определяет следующие классы механизма:


Отметьте: генератор создает объекты с совершенно новым содержанием, тогда как фабрика создает объекты из существующего материала (например, кодирование).


Механизм class обеспечивает интерфейс для функциональности определенного типа криптографической службы (независимый от определенного криптографического алгоритма). Это определяет Прикладной программный интерфейс (API) методы, которые позволяют приложениям получать доступ к определенному типу криптографической службы, которую это обеспечивает. Фактические реализации (от одного или более провайдеров) являются теми для определенных алгоритмов. Например, механизм Подписи class обеспечивает доступ к функциональности алгоритма цифровой подписи. Фактическая реализация предоставляется в a SignatureSpi подкласс (см. следующий абзац) был бы то, что для определенного вида алгоритма подписи, такого как SHA1 с DSA, SHA1 с RSA, или MD5 с RSA.

Интерфейсы приложения, предоставленные механизмом class, реализуются с точки зрения Интерфейса Поставщика услуг (SPI). Таким образом, для каждого механизма class есть соответствующий абстрактный SPI class, который определяет методы Service Provider Interface, которые должны реализовать провайдеры криптографических служб.

Архитектура Интерфейса Поставщика услуг

Экземпляр механизма class, "объект API", инкапсулирует (как частное поле) экземпляр соответствующего SPI class, "объект SPI". Все методы API объекта API объявляются "финалом", и их реализации вызывают соответствующие методы SPI инкапсулировавшего объекта SPI. Экземпляр механизма class (и его соответствующего SPI class) создается звонком getInstance метод фабрики механизма class.

Имя каждого SPI class является тем же самым как тем из соответствующего механизма class, сопровождаемый "Spi". Например, SPI class, соответствующий механизму Подписи class, является SignatureSpi class.

Каждый SPI class абстрактен. Чтобы предоставить реализацию определенного типа службы и для определенного алгоритма, провайдер должен разделить соответствующий SPI на подклассы class и обеспечить реализации для всех абстрактных методов.

Другой пример механизма, class является MessageDigest class, который обеспечивает доступ к алгоритму обзора сообщения. Его реализации, в подклассах MessageDigestSpi, могут быть таковыми из различных алгоритмов обзора сообщения, таких как SHA 1, MD5, или MD2.

Как заключительный пример, механизм KeyFactory class поддерживает преобразование от непрозрачных ключей до прозрачных ключевых спецификаций, и наоборот. См. Ключевые Интерфейсы Спецификации и Классы, Необходимые Ключевыми Фабриками для деталей. Фактическая реализация, предоставленная в подклассе KeyFactorySpi, состояла бы в том что для определенного типа ключей, например, DSA открытые и закрытые ключи.

Шаги, чтобы Реализовать и Интегрировать Провайдера

Следуйте за шагами ниже, чтобы реализовать провайдера и интегрировать его в платформу JCA:

Шаг 1: Запишите свой Код Реализации Службы

Первая вещь, которую Вы должны сделать, состоит в том, чтобы записать код, который обеспечивает специфичные для алгоритма реализации криптографических служб, которые Вы хотите поддерживать.

Отметьте, что Ваш провайдер может предоставить реализации криптографических служб, уже доступных в один или больше компонентов безопасности JDK.

Для криптографических служб, не определенных в JCA (Например; подписи и обзоры сообщения), пожалуйста, сошлитесь на Справочник Архитектуры Криптографии Java.

Для каждой криптографической службы Вы хотите реализовать, создать подкласс соответствующего SPI class. JCA определяет следующие классы механизма:

(См. Классы Механизма и Соответствующие Классы SPI в этом документе для информации о JCA и другие криптографические классы.)

В Вашем подклассе Вы нуждаетесь к:

  1. Реализации предоставления для абстрактных методов, имена которых обычно начинаются engine. См. Дальнейшие Детали Реализации и Требования для дополнительной информации.
  2. Гарантируйте, что есть общедоступный конструктор без любых параметров. Вот то, почему: Когда одну из Ваших служб требуют, Безопасность Java ищет подкласс, реализовывая ту службу, как определено свойством в Вашем "основном class" (см. Шаг 3). Безопасность Java тогда создает Class объект, связанный с Вашим подклассом, и, создает экземпляр Вашего подкласса, вызывая newInstance метод на этом Class объект. newInstance требует, чтобы у Вашего подкласса был общедоступный конструктор без любых параметров.
  3. Конструктор по умолчанию без параметров будет автоматически сгенерирован, если у Вашего подкласса не будет никаких конструкторов. Но если Ваш подкласс определяет каких-либо конструкторов, следует явно определить общедоступного конструктора без параметров.

Шаг 1.1: Дополнительные Требования Провайдера JCA и Рекомендации для Реализаций Шифрования

Инстанцируя реализации провайдера (class) a Cipher, KeyAgreement, KeyGenerator, MAC или SecretKey фабрика, платформа определит кодовую базу провайдера (файл JAR) и проверит его подпись. Таким образом JCA аутентифицирует провайдера и гарантирует, что только провайдеры, подписанные доверяемым объектом, могут быть включены в JCA. Таким образом одно требование для провайдеров шифрования - то, что они должны быть подписаны, как описано в более поздних шагах.

Кроме того, каждый провайдер должен выполнить проверку самоцелостности, чтобы гарантировать, что файлом JAR, содержащим его код, не управляли в попытке вызвать методы провайдера непосредственно, а не через JCA. Для дополнительной информации см., Как Провайдер Может Сделать Проверку Самоцелостности.

Для классов провайдера, чтобы стать неприменимый если инстанцировано приложением непосредственно, обходя JCA, провайдеры должны реализовать следующее:

Для провайдеров, которые могут быть экспортированы вне США, CipherSpi реализации должны включать реализацию engineGetKeySize метод, который, данный a Key, возвращает размер ключа. Если есть ограничения на доступную криптографическую силу, определенную в файлах политики юрисдикции, каждом Cipher вызовы метода инициализации engineGetKeySize и затем сравнивает результат с максимальным допустимым размером ключа для определенного расположения и обстоятельств апплета или запущенного приложения. Если размер ключа является слишком большим, метод инициализации выдает исключение.

Дополнительные дополнительные функции, которые могут реализовать провайдеры,

Шаг 2: Дайте Вашему Провайдеру Имя

Выберите имя для своего провайдера. Это - имя, которое будет использоваться клиентскими приложениями, чтобы обратиться к Вашему провайдеру.

Шаг 3: Запишите свой Мастер класс, подкласс Провайдера

Третий шаг должен создать подкласс java.security.Provider class.

Ваш подкласс должен быть a final class, и его конструктор должны

В каждом из них, algName, certType, storeType, или attrName "стандартное" имя алгоритма, типа сертификата, keystore тип, или атрибут. (См. Приложение A Справочника Архитектуры Криптографии Java для стандартных имен, которые должны использоваться.)

Для свойства в вышеупомянутом формате значение свойства должно быть значением для соответствующего атрибута. (См. Приложение A Спецификации API Архитектуры Криптографии Java & Ссылки для определения каждого стандартного атрибута.)

Как пример, провайдер значения по умолчанию под названием "SUN" реализует SHA1withDSA Digital Алгоритм подписи в программном обеспечении. В основном class для провайдера "SUN" это устанавливает Signature.SHA1withDSA ImplementedIn иметь значение Software через следующее:

    put("Signature.SHA1withDSA ImplementedIn", "Software")

Для дальнейших основных примеров подающего свойства class см. Приложение A, чтобы просмотреть текущий исходный файл Sun.java или Приложение B, чтобы видеть провайдера SunJCE. Эти файлы показывают как свойства набора провайдеров Sun и SunJCE.

Шаг 3.1: Дополнительные Шаги для Реализаций Шифра

Как упомянуто выше, в случае a Cipher свойство, algName может фактически представить преобразование. Преобразование является строкой, которая описывает работу (или набор операций), чтобы быть выполненной a Cipher объект на некотором данном вводе. Преобразование всегда включает имя криптографического алгоритма (например, DES), и может сопровождаться режимом и дополнительной схемой.

Преобразование имеет форму:

(В последнем случае специфичные для провайдера значения по умолчанию для режима и дополнительной схемы используются). Например, следующее является допустимым преобразованием:

    Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding"); 

Запрашивая блочный шифр в режиме поточного шифра (например; DES в CFB или OFB режим), клиент может дополнительно определить число битов, которые будут обработаны за один раз, добавляя это число к имени режима как показано в следующих демонстрационных преобразованиях:

    Cipher c1 = Cipher.getInstance("DES/CFB8/NoPadding");
    Cipher c2 = Cipher.getInstance("DES/OFB32/PKCS5Padding");

Если число не следует за режимом поточного шифра, специфичное для провайдера значение по умолчанию используется. (Например, провайдер SunJCE использует значение по умолчанию 64 битов.)

Провайдер может предоставить отдельный class для каждой комбинации алгоритма/режима/дополнения. Альтернативно, провайдер может решить обеспечить больше универсальных классов, представляющих подпреобразования, соответствующие алгоритму или алгоритму/режиму, или алгоритм//дополняющий (отметьте двойные наклонные черты); в этом случае требуемый режим и/или дополнение устанавливаются автоматически getInstance методы Cipher, которые вызывают engineSetMode и engineSetPadding методы подкласса провайдера CipherSpi.

Таким образом, a Cipher у свойства в ведущем устройстве провайдера class может быть один из форматов, показанных в таблице ниже.

Cipher Формат свойства Описание
Cipher.algName Подкласс провайдера CipherSpi реализации algName со сменным режимом и дополнением
Cipher.algName/mode Подкласс провайдера CipherSpi реализации algName в указанном режиме, со сменным дополнением
Cipher.algName//дополнение Подкласс провайдера CipherSpi реализации algName с указанным дополнением, со сменным режимом
Cipher.algName/mode/padding Подкласс провайдера CipherSpi реализации algName с указанным режимом и дополнением

(См. Приложение A Справочника Архитектуры Криптографии Java для стандартных имен алгоритма, режимов, и дополнительных схем, которые должны использоваться.)

Например, провайдер может предоставить подкласс CipherSpi это реализует DES/ECB/PKCS5Padding, тот, который реализует DES/CBC/PKCS5Padding, тот, который реализует DES/CFB/PKCS5Padding, и еще один, который реализует DES/OFB/PKCS5Padding. У того провайдера был бы следующий Cipher свойства в его основном class:

Другой провайдер может реализовать class для каждого из вышеупомянутых режимов (то есть, один class для ECB, один для CBC, один для CFB, и один для OFB), один class для PKCS5Padding, и универсальный DES class, который разделяет на подклассы от CipherSpi. У того провайдера был бы следующий Cipher свойства в его основном class:

getInstance метод фабрики Cipher class механизма следует за этими правилами, чтобы инстанцировать реализации провайдера CipherSpi для преобразования формы "алгоритм":

  1. Проверьте, зарегистрировал ли провайдер подкласс CipherSpi для указанного "алгоритма".

    Если ответ ДА, инстанцируйте этого class, для того, используются режим которого и дополнительные значения по умолчанию схемы (как предоставлено провайдером).

    Если ответ нет, бросок a NoSuchAlgorithmException исключение.

getInstance метод фабрики Cipher class механизма следует за этими правилами, чтобы инстанцировать реализации провайдера CipherSpi для преобразования формы "алгоритм/режим/дополнение":

  1. Проверьте, зарегистрировал ли провайдер подкласс CipherSpi для указанного преобразования "алгоритма/режима/дополнения".

    Если ответ ДА, инстанцируйте его.

    Если ответ нет, пойдите в следующий шаг.
  2. Проверьте, зарегистрировал ли провайдер подкласс CipherSpi для подпреобразования "алгоритм/режим".

    Если ответ ДА, инстанцируйте его, и вызов engineSetPadding(padding) на новом экземпляре.

    Если ответ нет, пойдите в следующий шаг.
  3. Проверьте, зарегистрировал ли провайдер подкласс CipherSpi для подпреобразования "алгоритм//дополняющий" (отмечают двойные наклонные черты).

    Если ответ ДА, инстанцируйте его, и вызов engineSetMode(mode) на новом экземпляре.

    Если ответ нет, пойдите в следующий шаг.
  4. Проверьте, зарегистрировал ли провайдер подкласс CipherSpi для подпреобразования "алгоритм".

    Если ответ ДА, инстанцируйте его, и вызов engineSetMode(mode) и engineSetPadding(padding) на новом экземпляре.

    Если ответ нет, бросок a NoSuchAlgorithmException исключение.

Шаг 4: Скомпилируйте свой Код

После того, как Вы создали свой код реализации (Шаг 1), учитывая Вашего провайдера имя (Шаг 2), и создали основной class (Шаг 3), используйте компилятор Java, чтобы скомпилировать Ваши файлы.

Шаг 5: Поместите Своего Провайдера в Файл JAR

Поместите свой код провайдера в файл JAR в подготовку к подписанию этого в следующем шаге. Для получения дополнительной информации по инструменту фляги см. флягу (для Соляриса) (для Microsoft Windows).

    jar cvf <JAR file name> <list of classes, separated by spaces>

Эта команда создает файл JAR с указанным именем, содержащим указанные классы.

Шаг 6: Дополнительный - Знак Ваш Файл JAR

Если Ваш провайдер предоставляет алгоритмы шифрования через Cipher KeyAgreement, KeyGenerator, Mac, или SecretKeyFactory классы, Вы должны будете подписать свой файл JAR так, чтобы JCA мог аутентифицировать код во времени выполнения. Для получения дополнительной информации см. Шаг 1a. Если Вы НЕ обеспечиваете реализацию этого типа, можно пропустить этот шаг.

Шаг 6.1: Получите Сертификат для подписывания кода

Следующий шаг должен запросить сертификат для подписывания кода так, чтобы можно было использовать его, чтобы подписать Вашего провайдера до тестирования. Сертификат будет хорош и для тестирования и для производства. Это будет допустимо в течение 5 лет.

Ниже шаги, которые следует использовать, чтобы получить сертификат для подписывания кода. Для получения дополнительной информации по keytool инструменту см. keytool (для Соляриса) (для Microsoft Windows).

  1. Используйте keytool, чтобы генерировать пару ключей DSA, используя алгоритм DSA в качестве примера:
        keytool -genkeypair -alias <alias> \
            -keyalg DSA -keysize 1024 \
            -dname "cn=<Company Name>, \
            ou=Java Software Code Signing,\
            o=Sun Microsystems Inc" \
            -keystore <keystore file name>\
            -storepass <keystore password>
            
    

    Это генерирует пару ключей DSA (открытый ключ и связанный закрытый ключ) и сохранит это в записи в указанном keystore. Открытый ключ сохранен в самоподписанном сертификате. К keystore записи можно впоследствии получить доступ, используя указанный псевдоним.


    Значения опции в угловых скобках (" <" и">") представляют фактические значения, которые должны быть предоставлены. Например, <alias> должен быть заменен любым псевдонимом, называют Вас, хотят использоваться, чтобы обратиться к недавно сгенерированной keystore записи в будущем, и <keystore file name> должен быть заменен именем keystore, который будет использоваться. Отметьте: не окружайте фактические значения угловыми скобками. Например, если Вы хотите, чтобы Ваш псевдоним был myTestAlias, определите -alias опция следующим образом:

        -alias myTestAlias
    
    Если Вы определите keystore, который еще не существует, то он будет создаваться.


    Отметьте: Если командным строкам, которые Вы вводите, не позволяют быть пока keytool -genkeypair команда, которую Вы хотите выполнить (например, если Вы вводите к командной строке DOS Microsoft Windows), можно создать и выполнить пакетный файл простого текста, содержащий команду. Таким образом, создайте новый текстовый файл, который содержит только полное keytool -genkeypair команда. (Не забудьте вводить все это на одной строке.) Сохранили файл с.bat расширением. Затем в Вашем окне DOS, введите имя файла (с его путем, в случае необходимости). Это заставит команду в пакетном файле выполняться.



  2. Используйте keytool, чтобы генерировать запрос подписания сертификата.
        keytool -certreq -alias <alias> \
            -file <csr file name> \
            -keystore <keystore file name> \
            -storepass <keystore password> 
    
    Здесь, <alias> псевдоним для записи пары ключей DSA, создаваемой в предыдущем шаге. Эта команда генерирует Запрос Подписания Сертификата (CSR), используя PKCS#10 формат. Это хранит CSR в файле, имя которого определяется в <csr file name>.
  3. Отправьте CSR, контактную информацию, и другую необходимую документацию к Центру сертификации Подписывания кода JCA. См. Центр сертификации Подписывания кода JCA для контактной информации.
  4. После того, как Центр сертификации Подписывания кода JCA получил Ваше электронное письмо, они отправят Вам число запроса по электронной почте. Как только Вы получаете это число запроса, следует напечатать, заполнить и отправить Форму Сертификации за CSPs. См. Передающую Форму Сертификации для CSPs для контактной информации.
  5. Используйте keytool, чтобы импортировать сертификаты, полученные от CA.

    Как только Вы получили эти два сертификата от Центра сертификации Подписывания кода JCA, можно использовать keytool, чтобы импортировать их в Ваш keystore.

    Сначала импортируйте сертификат CA как "доверяемый сертификат":
        keytool -import -alias <alias for the CA cert> \
            -file <CA cert file name> \
            -keystore <keystore file name> \
            -storepass <keystore password>
    
    Затем импортируйте сертификат для подписывания кода:
        keytool -import -alias <alias> \
            -file <code-signing cert file name> \
            -keystore <keystore file name> \
            -storepass <keystore password>
    
    Здесь, <alias> тот же самый псевдоним как то, что Вы создали в шаге 1, где Вы генерировали пару ключей DSA. Эта команда заменяет самоподписанный сертификат в keystore записи, определенной <alias> с тем, подписанным Центром сертификации Подписывания кода JCA.

Теперь, когда у Вас есть в Вашем keystore сертификат от объекта, которому доверяет JCA (Центр сертификации Подписывания кода JCA), можно поместить свой код провайдера в файл JAR (Шаг 5) и затем использовать тот сертификат, чтобы подписать файл JAR (Шаг 6.2).

Шаг 6.2: Подпишите Своего Провайдера

Подпишите файл JAR создаваемый шаг пять с сертификатом для подписывания кода, полученным в Шаге 6. Для получения дополнительной информации по jarsigner инструменту см. jarsigner (для Соляриса) (для Microsoft Windows).

    jarsigner -keystore <keystore file name> \
        -storepass <keystore password> \
        <JAR file name> <alias>

Здесь, <alias> псевдоним в keystore для записи, содержащей сертификат для подписывания кода, полученный от Центра сертификации Подписывания кода JCA (тот же самый псевдоним, поскольку это определило в командах в Шаге 6.1).

Можно протестировать проверку подписи через следующее:

    jarsigner -verify <JAR file name> 

Текст "фляга, проверенная", будет выведен на экран, если проверка была успешна.

Шаг 7: Подготовьтесь к Тестированию

Следующие шаги описывают, как установить и сконфигурировать Вашего нового провайдера так, чтобы это было доступно через JCA.

Шаг 7.1: Установите Провайдера

Чтобы подготовиться к тестированию Вашего провайдера, следует установить его тем же самым способом, как будет сделан клиентами, желающими использовать это. Установка позволяет Безопасности Java найти Ваши реализации алгоритма, когда клиенты запрашивают их.

Установка провайдера делается в двух шагах: установка классов пакета провайдера, и конфигурирование провайдера.

Установка Классов Провайдера

Первая вещь, которую следует сделать, делают Ваши классы доступными так, чтобы они могли быть найдены когда требующийся. Вы поставляете свои классы провайдера как JAR (Архив Java) файл.

Есть два возможные способы установить классы провайдера:

Файл JAR провайдера будут считать установленным расширением, если он будет помещен в стандартное место для файлов JAR установленного расширения:

    <java-home>/lib/ext           [Solaris]
    <java-home>\lib\ext           [Windows]

Здесь <java-home> ссылается на каталог, где программное обеспечение времени выполнения устанавливается, который является высокоуровневым каталогом Java™ 2 Среды выполнения (JRE) или каталог jre в Java™ SE (JDK) программное обеспечение. Например, если у Вас есть JDK 6 установленный на Солярисе в названном каталоге /home/user1/jdk1.6.0, или на Microsoft Windows в каталоге называется C:\jdk1.6.0, тогда Вы должны установить файл JAR в следующем каталоге:

    /home/user1/jdk1.6.0/jre/lib/ext    [Solaris]
    C:\jdk1.6.0\jre\lib\ext             [Windows]

Точно так же, если у Вас есть JRE 6 установленный на Солярисе в названном каталоге /home/user1/jre1.6.0, или на Microsoft Windows в каталоге называется C:\jre1.6.0, Вы должны установить файл JAR в следующем каталоге:

    /home/user1/jre1.6.0/lib/ext        [Solaris]
    C:\jre1.6.0\lib\ext                 [Windows]

Для получения дополнительной информации по установленным расширениям см. Установленные Расширения.

Для получения дополнительной информации по связанным расширениям см. Связанные Расширения.

Конфигурирование Провайдера

Следующий шаг должен добавить провайдера к Вашему списку одобренных провайдеров. Это делается статически, редактируя файл свойств безопасности

    <java-home>/lib/security/java.security        [Solaris]
    <java-home>\lib\security\java.security        [Windows]

Здесь <java-home> ссылается на каталог, где JRE был установлен. Например, если у Вас есть JDK 6 установленный на Солярисе в названном каталоге /home/user1/jdk1.6.0, или на Microsoft indows в каталоге называется C:\jdk1.6.0, тогда Вы должны отредактировать следующий файл:

    /home/user1/jdk1.6.0/jre/lib/security/java.security [Solaris]
    C:\jdk1.6.0\jre\lib\security\java.security          [Windows]

Точно так же, если у Вас есть JRE 6 установленный на Солярисе в названном каталоге /home/user1/jre1.6.0, или на Windows в каталоге называется C:\jre1.6.0, тогда Вы должны отредактировать этот файл:

    /home/user1/jre1.6.0/lib/security/java.security     [Solaris]
    C:\jre1.6.0\lib\security\java.security              [Windows]

Для каждого провайдера у этого файла должен быть оператор следующей формы:

    security.provider.n=masterClassName 

Это объявляет провайдера, и определяет его привилегированный порядок n. Привилегированный порядок является порядком, в котором провайдеры ищутся требуемые алгоритмы, когда никакого определенного провайдера не требуют. Порядок на основе 1; 1 является самым привилегированным, сопровождается 2, и так далее.

masterClassName должен определить полностью определенное имя "основного class провайдера", который Вы реализовывали в Шаге 3. Этот class всегда является подклассом Провайдера class.

Java прибывает стандарт с провайдерами под названием SUN, SunRsaSign, и SunJCE, которые автоматически конфигурируются как статический провайдер в java.security файл свойств, следующим образом:

    security.provider.2=sun.security.provider.Sun
    security.provider.3=sun.security.rsa.SunRsaSign
    security.provider.4=sun.security.provider.SunJCE

(Основной class провайдера Sun Sun class в sun.security.provider пакет.)

Провайдер JCA SunJCE и другие связанные с безопасностью провайдеры, поставленные с платформой Java, также автоматически конфигурируется как статические провайдеры.

Чтобы использовать другого провайдера JCA, добавьте строку, регистрирующую альтернативного провайдера, давая это более низкий привилегированный порядок чем провайдеры SUN и SunRsaSign.

Предположите, что Ваш основной class CryptoX class в com.cryptox.provider пакет, и что требуется сделать своего провайдера четвертым привилегированным провайдером. Чтобы сделать так, отредактируйте java.security файл как замечено ниже:

    security.provider.2=sun.security.provider.Sun
    security.provider.3=sun.security.rsa.SunRsaSign
    security.provider.4=com.cryptox.provider.CryptoX
    security.provider.5=sun.security.provider.SunJCE

Отметьте: Провайдеры могут также быть зарегистрированы динамически. Чтобы сделать так, программа (такая как Ваша тестовая программа, быть записанными в Шаге 8) может вызвать любого addProvider или insertProviderAt метод в Security class. Этот тип регистрации не является персистентным и может только быть сделан кодом, которому предоставляют следующее разрешение:

    java.security.SecurityPermission "insertProvider.{name}"

где {name} заменяется фактическим именем провайдера.

Например, если имя провайдера является "MyJCE" и если код провайдера находится в myjce_provider.jar файл в /localWork каталог, тогда вот демонстрационный файл политики grant оператор, допускающий, что разрешение:

    grant codeBase "file:/localWork/myjce_provider.jar" {
        permission java.security.SecurityPermission
            "insertProvider.MyJCE";
    };

Шаг 7.2: Полномочия Провайдера Набора

Всякий раз, когда провайдеры не являются установленными расширениями, полномочия нужно предоставить для того, когда апплеты или приложения выполняются, в то время как менеджер безопасности устанавливается. обычно есть менеджер безопасности, установленный всякий раз, когда апплет работает, и менеджер безопасности может быть установлен для приложения или через код в приложении непосредственно или через параметр командной строки. Полномочия не должны предоставить установленным расширениям, так как системный файл политики значения по умолчанию предоставляет все полномочия установленным расширениям.

Всякий раз, когда клиент не устанавливает Вашего провайдера как установленное расширение, Вашему провайдеру, возможно, понадобятся следующие полномочия, предоставленные ему в клиентской среде:

Гарантировать Вашего провайдера работает, когда менеджер безопасности устанавливается, и провайдер не является установленным расширением, Вы должны протестировать такую установку и среду выполнения. Кроме того, до тестирования Вы должны предоставить соответствующие полномочия своему провайдеру и любым другим провайдерам, которых это использует. Например, демонстрационное предоставление оператора полномочия к провайдеру, имя которого является "MyJCE" и чей код находится в myjce_provider.jar появляется ниже. Такой оператор мог появиться в файле политики. В этом примере, myjce_provider.jar файл, как предполагается, находится в /localWork каталог.

    grant codeBase "file:/localWork/myjce_provider.jar" {
        permission java.lang.RuntimePermission "getProtectionDomain";
        permission java.security.SecurityPermission
            "putProviderProperty.MyJCE";
    };

Шаг 8: Запишите и Компиляция Ваши Тестовые программы

Запишите и скомпилируйте одну или более тестовых программ, которые тестируют объединение Вашего провайдера в API Безопасности так же как правильность его алгоритма (ов). Создайте любые необходимые вспомогательные файлы, такие как те для данных тестирования, которые будут зашифрованы.

Первые тесты, которые должна выполнить Ваша программа, являются, чтобы гарантировать, что Ваш провайдер находится, и что его имя, номер версии, и дополнительная информация как ожидалось. Чтобы сделать так, Вы могли записать код как следующий, заменяя Вашим именем провайдера MyPro:

    import java.security.*;

    Provider p = Security.getProvider("MyPro");

    System.out.println("MyPro provider name is " + p.getName());
    System.out.println("MyPro provider version # is " + p.getVersion());
    System.out.println("MyPro provider info is " + p.getInfo());

Затем, следует гарантировать, что Ваши службы находятся. Например, если бы Вы реализовывали алгоритм шифрования DES, то Вы могли бы проверить, чтобы гарантировать, что это находится когда требующийся при использовании следующего кода (снова заменяющий Вашим именем провайдера "MyPro"):

    Cipher c = Cipher.getInstance("DES", "MyPro");

    System.out.println("My Cipher algorithm name is " + c.getAlgorithm());

Если Вы не определяете, что провайдер называет в звонке getInstance, все зарегистрированные провайдеры будут искаться в привилегированном порядке (см. Конфигурирование Провайдера), пока одна реализация алгоритма не находится.

Если Ваш провайдер реализует механизм освобождения, следует записать тестовый апплет или приложение, которое использует механизм освобождения. Такой апплет/приложение также должен быть подписан, и должен иметь "файл политики разрешения", связанный этим. См., Как Подать Заявки, "Освобожденные" от Криптографических Ограничений в Справочнике Архитектуры Криптографии Java для полной информации о создании и тестировании такого приложения.

Шаг 9: Выполните свои Тестовые программы

Выполните свою тестовую программу (ы). Отладьте свой код и продолжайте тестировать как необходимый. Если API Безопасности Java, может казаться, не находит один из Ваших алгоритмов, не рассматривает шаги выше и не гарантирует, что они все завершаются.

Убедитесь, что включали тестирование своих программ, используя различные опции инсталляции (например, делающий провайдера установленное расширение или помещающий это в путь class) и среды выполнения (с или без выполнения менеджера безопасности). Опции инсталляции обсуждаются в Шаге 7.1. В частности Вы должны гарантировать свои работы провайдера, когда менеджер безопасности устанавливается, и провайдер не является установленным расширением - и таким образом провайдеру нужно было предоставить полномочия этому; поэтому, Вы должны протестировать такую установку и среду выполнения после предоставления необходимых полномочий к Вашему провайдеру и к любым другим провайдерам, которых это использует, как описано в Шаге 7.2.

Если Вы находите во время тестирования, что Ваш код нуждается в модификации, произведите изменения, перекомпилируйте (Шаг 4), поместите обновленный код провайдера в файл JAR (Шаг 6), подпишите файл JAR в случае необходимости (Шаг 6.2), переустановите провайдера (Шаг 7.1), если нужно фиксируйте или добавьте к полномочиям (Шаг 7.2), и затем повторно протестируйте Ваши программы. Повторите эти шаги как необходимый.

Шаг 10: Просите американское правительственное Одобрение Экспорта Если Требующийся

Все американские поставщики, провайдеры которых могут быть экспортированы вне США, должны примениться к Бюро Отрасли и Безопасности в американском Министерстве торговли для одобрения экспорта. Пожалуйста, консультируйтесь со своим адвокатом экспорта для получения дополнительной информации.

Отметьте: Если Ваш провайдер вызывает Cipher.getInstance() и возвращенный Cipher возразите должен выполнить криптографию strong независимо от того, что криптографическая сила позволяется загруженными файлами политики юрисдикции пользователя, следует включать копию cryptoPerms файл политики разрешения, который Вы намереваетесь связать в файле JAR для Вашего провайдера и который определяет соответствующее разрешение для необходимой криптографической силы. Потребность этого файла точно так же как требование, чтобы апплеты и приложения, "освобожденные" от криптографических ограничений, включали a cryptoPerms файл политики разрешения в их файле JAR. Для получения дополнительной информации по созданию и включению такого файла, см., Как Подать Заявки, "Освобожденные" от Криптографических Ограничений в Справочнике Архитектуры Криптографии Java.

Вот два URL, которые могут быть полезными:

Шаг 11: Задокументируйте своего Провайдера и его Поддерживаемые Службы

Следующий шаг должен записать документацию для Ваших клиентов. В минимуме Вы должны определить:

Кроме того, Ваша документация должна определить что-либо еще интереса для клиентов, таких как любые параметры алгоритма значения по умолчанию.

Обзоры сообщения и MACs

Для каждого сообщения Обзор и алгоритм MAC, укажите, является ли Ваша реализация cloneable. Это не технически необходимо, но это может сэкономить клиентам некоторое время и кодирование, говоря им, передает ли промежуточное звено Обзоры, или MACs может быть возможным посредством клонирования. Клиенты, которые не знают действительно ли a MessageDigest или Mac реализация является cloneable, может узнать, пытаясь клонировать объект и ловя потенциальное исключение, как иллюстрировано следующим примером:

    try {
        // try and clone it
        /* compute the MAC for i1 */
        mac.update(i1);
        byte[] i1Mac = mac.clone().doFinal();

        /* compute the MAC for i1 and i2 */
        mac.update(i2);
        byte[] i12Mac = mac.clone().doFinal();

        /* compute the MAC for i1, i2 and i3 */
        mac.update(i3);
        byte[] i123Mac = mac.doFinal();
    } catch (CloneNotSupportedException cnse) {
        // have to use an approach not involving cloning
    } 

где:

Генераторы Пары ключей

Для алгоритма генератора пары ключей, в случае, если клиент явно не инициализирует генератор пары ключей (через звонок initialize метод), каждый провайдер должен предоставить и задокументировать инициализацию значения по умолчанию. Например, генератор пары ключей Diffie-Hellman, предоставленный провайдером SunJCE, использует значение по умолчанию главный размер модуля (keysize) из 1024 битов.

Ключевые Фабрики

Провайдер должен задокументировать все ключевые спецификации, поддерживаемые (секрет-) ключевая фабрика.

Генераторы Параметра алгоритма

В случае, если клиент явно не инициализирует генератор параметра алгоритма (через звонок init метод в AlgorithmParameterGenerator механизм class), каждый провайдер должен предоставить и задокументировать инициализацию значения по умолчанию. Например, провайдер SunJCE использует значение по умолчанию главный размер модуля (keysize) из 1024 битов для генерации параметров Diffie-Hellman, провайдер Sun модуль значения по умолчанию главный размер 1024 битов для генерации параметров DSA.

Алгоритмы подписи

Если Вы реализуете алгоритм подписи, следует задокументировать формат в который подпись (сгенерированный одним из sign методы), кодируется. Например, алгоритм подписи SHA1withDSA, предоставленный провайдером "SUN", кодирует подпись как стандарт ASN.1 SEQUENCE из двух целых чисел, r и s.

Генерация случайных чисел (SecureRandom) Алгоритмы

Для алгоритма генерации случайных чисел предоставьте информацию относительно того, насколько "случайный" сгенерированные числа, и качество семени, когда генератор случайных чисел является самоотбором. Также отметьте то, что происходит, когда объект SecureRandom (и его инкапсулировавший объект реализации SecureRandomSpi) десериализовываются: Если последующие звонки nextBytes метод (который вызывает engineNextBytes метод инкапсулировавшего объекта SecureRandomSpi) восстановленного объектного урожая, те же самые (случайные) байты как исходный объект были бы, затем позвольте пользователям знать, что, если это поведение является нежелательным, они должны отобрать восстановленный случайный объект, вызывая setSeed метод.

Фабрики сертификата

Провайдер должен задокументировать, какие типы сертификатов (и их номера версий, если релевантный), может быть создан фабрикой.

Keystores

Провайдер должен задокументировать любую релевантную информацию относительно keystore реализации, такой как ее базовый формат данных.

Шаг 12: Сделайте свои Файлы Класса и Документацию Доступными для Клиентов

После записи, конфигурирования, тестирование, установка и документирование Вашего программного обеспечения провайдера, делает документацию доступной для Ваших клиентов.

Как Провайдер Может Сделать Проверку Самоцелостности

Каждый провайдер должен сделать проверку самоцелостности, чтобы гарантировать, что в файл JAR, содержащий его код, не вмешались, например в попытке вызвать методы провайдера непосредственно, а не через JCA. Провайдеры, которые обеспечивают реализации для служб шифрования (Cipher, KeyAgreement, KeyGenerator, MAC или SecretKey фабрика), должен быть в цифровой форме подписан и должен быть подписан с сертификатом, выпущенным "доверяемыми" Центрами сертификации. В настоящий момент следующие два Центра сертификации считают "доверяемыми":

Пожалуйста, обратитесь к Шагу 6.2 для получения дальнейшей информации на том, как получить сертификат для подписывания кода от CA Подписывания кода Sun Microsystems JCA и сертификата о том CA.

После получения сертификата подписания от вышеупомянутого Центра сертификации пакеты провайдера должны встроить в пределах себя байты для его собственного сертификата подписания, например в массиве как bytesOfProviderCert массив, упомянутый в Идентификации Каждого из Подписывающих лиц и Определения, Если Вы - раздел, Которому доверяют, ниже. Во времени выполнения встроенный сертификат будет использоваться в определении, подлинен ли код провайдера.

Основной подход, который провайдер может использовать, чтобы проверить его собственную целостность:

  1. Определите URL файла JAR, содержащего код провайдера, и
  2. Проверьте цифровые подписи файла JAR, чтобы гарантировать, что по крайней мере одному подписывающему лицу каждой записи файла JAR доверяют.

Каждый из этих шагов описывается в следующих разделах:

Примечания по Примеру кода

Отметьте: пример кода MyJCE.java полный пример кода, который реализует эти шаги. Можно загрузить этот код для своей ссылки. Примечания по разделу Примера кода прослеживают, как эти понятия реализуются в примере кода.


ВАЖНОЕ ПРИМЕЧАНИЕ: В несвязанной версии JCE 1.2.x, (используемый с JDKs 1.2.x и 1.3.x), провайдеры должны были включать код, чтобы аутентифицировать платформу JCA, чтобы убедиться целостности и подлинность JCA, что они включили. В JDK 6, это больше не необходимо.

Одна импликация - то, что провайдер, записанный только для JCE 1.2.2, не будет работать в JDK 6, потому что проверка аутентификации платформы провайдера JCE не будет работать; код платформы JCE больше не, где провайдер ожидает, что это будет. Если Вы хотите, чтобы Ваш провайдер работал только с JDK 6, у этого не должно быть кода, чтобы аутентифицировать платформу JCE. С другой стороны, если Вы хотите, чтобы Ваш провайдер работал и с JCE 1.2.2 и с JDK 6, затем добавьте условный оператор. Этим путем код провайдера, чтобы аутентифицировать платформу JCE выполняется только, когда провайдер выполняется с JCE 1.2.2. Следующее является примером кода:

    Class cipherCls = Class.forName("javax.crypto.Cipher");

    CodeSource cs = cipherCls.getProtectionDomain().getCodeSource();
    if (cs != null) {
        // Authenticate JCE framework
. . . }

Обнаружение Файла JAR Провайдера: Основы

Определение Файла JAR Провайдера URL

URL для файла JAR провайдера может быть получен, определяя провайдера CodeSource и затем вызов getLocation метод на CodeSource.

    URL providerURL = (URL) AccessController.doPrivileged(
        new PrivilegedAction) {
            public Object run() {
                CodeSource cs =
                    MyJCE.class.getProtectionDomain().getCodeSource();
                return cs.getLocation();
            }
        }); 

Создание JarFile что касается Файла JAR

Как только у Вас есть URL для файла JAR провайдера, можно создать a java.util.jar.JarFile обращение к файлу JAR. Этот экземпляр необходим в шаге для того, чтобы проверить файл JAR Провайдера.

Чтобы создать файл JAR, сначала откройте соединение с указанным URL, вызывая openConnection метод. Так как URL является JAR URL, тип java.net.JarURLConnection. Вот абсолютный код:

    // Prep the url with the appropriate protocol.
    jarURL =
        url.getProtocol().equalsIgnoreCase("jar") ? url :
            new URL("jar:" + url.toString() + "!/");

    // Retrieve the jar file using JarURLConnection
    JarFile jf = (JarFile) AccessController.doPrivileged(
        new PrivilegedExceptionAction() {
            public Object run() throws Exception {
                JarURLConnection conn =
                    (JarURLConnection) jarURL.openConnection();
        ...  

Теперь, когда у Вас есть a JarURLConnection, можно вызвать getJarFile метод, чтобы получить файл JAR:

    // Always get a fresh copy, so we don't have to
    // worry about the stale file handle when the
    // cached jar is closed by some other application.
    conn.setUseCaches(false);
    jf = conn.getJarFile(); 

Проверка Файла JAR Провайдера: Основы

Как только Вы определили URL для своего файла JAR провайдера, и Вы создали a JarFile обращаясь к файлу JAR, как показано в шагах выше, можно тогда проверить файл.

Основной подход:

  1. Гарантируйте, что по крайней мере один из сертификатов подписывающего лица каждой записи равен собственному сертификату для подписывания кода провайдера.
  2. Пройдите через все записи в файле JAR и гарантируйте, что подпись на каждом проверяет правильно.
  3. Гарантируйте, что по крайней мере один из сертификатов подписывающего лица каждой записи может быть прослежен до доверяемого Центра сертификации.

Пример кода для каждого из этих шагов представляется и описывается в следующих разделах:

Установка проверки

Наш подход должен определить class JarVerifier обработать извлечение файла JAR от данного URL и проверить, подписывается ли файл JAR с указанным сертификатом.

Конструктор JarVerifier берет провайдера URL в качестве параметра, который будет использоваться, чтобы получить файл JAR позже.

Фактическая проверка фляги реализуется в verify метод, который берет сертификат для подписывания кода провайдера в качестве параметра.

    public void verify(X509Certificate targetCert) throws IOException {
        // variable 'jarFile' is a JarFile object created
        // from the provider's Jar URL.
        ...
        Vector entriesVec = new Vector(); 

В основном verify метод пройдет через записи файла JAR дважды: первому разу, проверяя подпись на каждой записи и во второй раз, проверяющий подписывающее лицо, доверяют.

Отметьте: В наших фрагментах кода jarFile переменная JarFile объект файла фляги провайдера.

Проверка Подписи Файла JAR

Подписывается подлинный файл JAR провайдера. Таким образом, в файл JAR вмешались, если он не подписывается:

    // Ensure the jar file is signed.
    Manifest man = jarFile.getManifest();
    if (man == null) {
        throw new SecurityException("The provider is not signed");
    } 

Проверка Подписей

Следующий шаг должен пройти через все записи в файле JAR и гарантировать, что подпись на каждом проверяет правильно. Один возможный способ проверить подпись на записи файла JAR состоит в том, чтобы просто считать файл. Если файл JAR подписывается, read метод непосредственно автоматически выполняет проверку подписи. Вот пример кода:

    // Ensure all the entries' signatures verify correctly
    byte[] buffer = new byte[8192];
    Enumeration entries = jarFile.entries();

    while (entries.hasMoreElements()) {
        JarEntry je = (JarEntry) entries.nextElement();

        // Skip directories.
        if (je.isDirectory())
            continue;

        entriesVec.addElement(je);
        InputStream is = jarFile.getInputStream(je);

        // Read in each jar entry. A security exception will
        // be thrown if a signature/digest check fails.
        int n;
        while ((n = is.read(buffer, 0, buffer.length)) != -1) {
            // Don't care
        }
        is.close();
    }
    

Доверяют гарантирующим Подписывающим лицам

Код в предыдущем разделе, проверенном подписи всех записей файла JAR провайдера. Фактом, что они все проверяют правильно, является требование, но не достаточно проверить подлинность файла JAR. Заключительное требование - то, что подписи были сгенерированы тем же самым объектом как тот, который разработал этого провайдера. Чтобы протестировать это, подписям доверяют, мы можем снова пройти через каждую запись в файле JAR (на сей раз, используя entriesVec созданный в предыдущем шаге), и для каждой записи, которая должна быть подписана (то есть, каждая запись, которая не является каталогом и это не находится в каталоге META-INF):

  1. Получите список сертификатов подписывающего лица для записи.
  2. Идентифицируйте каждую из цепочек сертификата и определите, доверяют ли какой-либо из цепочек сертификата. По крайней мере одной из цепочек сертификата нужно доверять.

Установка цикла является следующим:

    Enumeration e = entriesVec.elements();
    while (e.hasMoreElements()) {
        JarEntry je = (JarEntry) e.nextElement();
        ...
    } 

Получение Списка Сертификатов

Сертификаты для подписывающих лиц записи файла JAR JarEntry может быть получен просто, вызывая JarEntry getCertificates метод:

    Certificate[] certs = je.getCertificates();

Добавление этой строки кода к предыдущему коду установки цикла, и добавление кода, чтобы проигнорировать каталоги и файлы в каталоге META-INF дают нам:

    while (e.hasMoreElements()) {
        JarEntry je = (JarEntry) e.nextElement();

        // Every file must be signed except files in META-INF.
        Certificate[] certs = je.getCertificates();
        if ((certs == null) || (certs.length == 0)) {
            if (!je.getName().startsWith("META-INF"))
                throw new SecurityException(
                    "The provider has unsigned class files.");
            } else {
                // Check whether the file is signed by the expected
                // signer. The jar may be signed by multiple signers.
                // See if one of the signers is 'targetCert'.
                ...
            }
        ...  

Идентификация Каждого из Подписывающих лиц и Определения, Если Вам Доверяют

Массив сертификата, возвращенный JarEntry getCertificates метод содержит одну или более цепочек сертификата. Есть одна цепочка на подписывающее лицо записи. Каждая цепочка содержит один или более сертификатов. Каждый сертификат в цепочке аутентифицирует открытый ключ в предыдущем сертификате.

Первый сертификат в цепочке является сертификатом подписывающего лица, который содержит открытый ключ, соответствующий закрытому ключу, фактически используемому, чтобы подписать запись. Каждый последующий сертификат является сертификатом для выпускающего предыдущего сертификата. Так как проверка самоцелостности основана на том, подписывается ли файл JAR со свидетельством подписания провайдера, доверительное решение будет принято на только первый сертификат, сертификат подписывающего лица.

Мы должны пройти через массив цепочек сертификата и проверить каждую цепочку и связанные подписывающие лица, пока мы не находим доверяемый объект. Для каждой записи файла JAR нужно доверять по крайней мере одному из подписывающих лиц. Подписывающее лицо считают "доверяемым", если и только если его сертификат, равняется встроенному сертификату подписания провайдера.

Следующие циклы примера кода через все цепочки сертификата, сравнивает первый сертификат в цепочке к встроенному сертификату подписания провайдера, и только возвращается true если соответствие находится.

    int startIndex = 0;
    X509Certificate[] certChain;
    boolean signedAsExpected = false;

    while ((certChain = getAChain(certs, startIndex)) != null) {
        if (certChain[0].equals(targetCert)) {
            // Stop since one trusted signer is found.
            signedAsExpected = true;
            break;
        }

        // Proceed to the next chain.
        startIndex += certChain.length;
    }

    if (!signedAsExpected) {
        throw new SecurityException(
            "The provider is not signed by a trusted signer");
    }
    

getAChain метод определяется следующим образом:

    /**
     * Extracts ONE certificate chain from the specified certificate array
     * which may contain multiple certificate chains, starting from index
     * 'startIndex'.
     */
    private static X509Certificate[] getAChain(
            Certificate[] certs, int startIndex) {

        if (startIndex > certs.length - 1)
            return null;

        int i;
        // Keep going until the next certificate is not the
        // issuer of this certificate.
        for (i = startIndex; i < certs.length - 1; i++) {
            if (!((X509Certificate)certs[i + 1]).getSubjectDN().
                    equals(((X509Certificate)certs[i]).getIssuerDN())) {
                break;
            }
        }

        // Construct and return the found certificate chain.
        int certChainSize = (i-startIndex) + 1;
        X509Certificate[] ret = new X509Certificate[certChainSize];
        for (int j = 0; j < certChainSize; j++ ) {
            ret[j] = (X509Certificate) certs[startIndex + j];
        }
        return ret;
    }
    

Примечания по myJCE Примеру кода

Пример кода, MyJCE.java, демонстрационный провайдер, у которого есть метод selfIntegrityChecking который выполняет проверку самоцелостности. Это сначала определяет URL своего собственного файла JAR провайдера и затем проверяет, что файл JAR провайдера подписывается со встроенным сертификатом для подписывания кода.

Отметьте: метод selfIntegrityChecking должен быть вызван всеми конструкторами его криптографических классов механизма, чтобы гарантировать, что его целостность не ставится под угрозу.

Провайдер MyJCE выполняет самоцелостность, регистрируясь в следующих шагах:

  1. Определите URL, чтобы получить доступ к файлу JAR провайдера, используя его собственный class, MyJCE.class.
  2. Инстанцируйте a JarVerifier объект с провайдером URL в Шаге 1.
  3. Создайте a X509Certificate объект от встроенного байтового массива bytesOfProviderCert.
  4. Вызовите JarVerifier.verify метод, чтобы проверить все записи в файле JAR провайдера подписывается и подписывается с тем же самым сертификатом, который инстанцируют в Шаге 3.

Отметьте: class JarVerifier получит файл JAR от данного URL, удостоверьтесь, что файл JAR подписывается, у всех записей есть действительные подписи, и это, записи подписываются с указанным X509Certificate.

Исключение безопасности выдается JarVerifier.verify в нескольких случаях:

MyJCE.java пример кода состоит из фрагментов кода, показанных выше. Кроме того, это включает обработку ошибок, пример кода, подписывая байты сертификата, и код для того, чтобы инстанцировать a X509Certificate объект из встроенного примера кода, подписывая байты сертификата.

Относительно использования AccessController.doPrivileged, пожалуйста, см. API Для Привилегированных Блоков для информации об использовании doPrivileged.

Дальнейшие Детали Реализации и Требования

-->

Имена псевдонима

Для многих криптографических алгоритмов и типов, есть единственное официальное "стандартное имя", определенное в Приложении A Справочника Архитектуры Криптографии Java.

Например, "MD5" является стандартным именем для сообщения RSA-MD5 алгоритм Обзора, определенный RSA DSI в RFC 1321. DiffieHellman стандарт для алгоритма согласования ключей Diffie-Hellman, определенного в PKCS3.

В JDK есть схема искажения, которая позволяет клиентам использовать псевдонимы, относясь к алгоритмам или типам, а не их стандартным именам. Например, основной class провайдера "SUN" (Sun.java) определяет псевдоним "SHA1/DSA" для алгоритма, стандартное имя которого является "SHA1withDSA". Таким образом следующие операторы эквивалентны:

    Signature sig = Signature.getInstance("SHA1withDSA", "SUN");

    Signature sig = Signature.getInstance("SHA1/DSA", "SUN");

Псевдонимы могут быть определены в Вашем "основном class" (см. Шаг 3). Чтобы определить псевдоним, создайте названное свойство

    Alg.Alias.engineClassName.aliasName

где engineClassName является именем механизма class (например, Signature), и aliasName является Вашим именем псевдонима. Значение свойства должно быть стандартным алгоритмом (или тип) имя для алгоритма (или тип) быть искаженным.

Как пример, провайдер "SUN" определяет псевдоним "SHA1/DSA" для алгоритма подписи, стандартное имя которого является "SHA1withDSA", устанавливая названное свойство Alg.Alias.Signature.SHA1/DSA иметь значение SHA1withDSA через следующее:

    put("Alg.Alias.Signature.SHA1/DSA", "SHA1withDSA");

Отметьте, что псевдонимы, определенные одним провайдером, доступны только тому провайдеру а не любым другим провайдерам. Таким образом псевдонимы, определенные провайдером SunJCE, доступны только провайдеру SunJCE.

Взаимозависимости службы

Некоторые алгоритмы требуют использования других типов алгоритмов. Например, алгоритм PBE обычно должен использовать алгоритм обзора сообщения, чтобы преобразовать пароль в ключ.

Если Вы реализуете один тип алгоритма, который требует другого, можно сделать одно из следующего:

  1. Предоставьте свои собственные реализации обоим.
  2. Позвольте своей реализации одного алгоритма использовать экземпляр другого типа алгоритма, как предоставлено значением по умолчанию провайдер Sun, который включается с каждым Java установка Платформы SE. Например, если Вы реализуете алгоритм PBE, который требует алгоритма обзора сообщения, можно получить экземпляр class, реализовывая алгоритм обзора сообщения MD5, вызывая
        MessageDigest.getInstance("MD5", "SUN")
  3. Позвольте своей реализации одного алгоритма использовать экземпляр другого типа алгоритма, как предоставлено другим определенным провайдером. Это является только соответствующим, если Вы уверены, что всем клиентам, которые будут использовать Вашего провайдера, также установят другого провайдера.
  4. Позвольте своей реализации одного алгоритма использовать экземпляр другого типа алгоритма, как предоставлено другим (неуказанным) провайдером. Таким образом, можно запросить алгоритм по имени, но не определяя определенного провайдера, как в
        MessageDigest.getInstance("MD5")
    Это является только соответствующим, если Вы уверены, что будет по крайней мере одна реализация требуемого алгоритма (в этом случае, MD5) установлена на каждой платформе Java, где Ваш провайдер будет использоваться.

Вот некоторые общие типы взаимозависимостей алгоритма:

Подпись и Алгоритмы Обзора сообщения

Алгоритм подписи часто требует использования алгоритма обзора сообщения. Например, алгоритм подписи SHA1withDSA требует SHA 1 алгоритм обзора сообщения.

Подпись и (псевдо-) Алгоритмы Генерации случайных чисел

Алгоритм подписи часто требует использования (псевдо-) алгоритм генерации случайных чисел. Например, такой алгоритм требуется, чтобы генерировать подпись DSA.

Генерация Пары ключей и Алгоритмы Обзора сообщения

Алгоритм генерации пары ключей часто требует использования алгоритма обзора сообщения. Например, ключи DSA сгенерированы, используя SHA 1 алгоритм обзора сообщения.

Генерация Параметра алгоритма и Алгоритмы Обзора сообщения

Генератор параметра алгоритма часто требует использования алгоритма обзора сообщения. Например, параметры DSA сгенерированы, используя SHA 1 алгоритм обзора сообщения.

KeyStores и Алгоритмы Обзора сообщения

keystore реализация будет часто использовать алгоритм обзора сообщения, чтобы вычислить хэширование по ключу (где key пользовательский указанный пароль) проверить целостность keystore и удостовериться, что в keystore не вмешались.

Алгоритмы Генерации Пары ключей и Генераторы Параметра Алгоритма

Алгоритм генерации пары ключей иногда должен генерировать новый набор параметров алгоритма. Это может или генерировать параметры непосредственно, или использовать генератор параметра алгоритма.

Генерация Пары ключей, Генерация Параметра Алгоритма, и (псевдо-) Алгоритмы Генерации случайных чисел

Алгоритм генерации пары ключей может потребовать источника случайности, чтобы генерировать новую пару ключей и возможно новый набор параметров, связанных с ключами. Тот источник случайности представляется a SecureRandom объект. Реализация алгоритма генерации пары ключей может генерировать основные параметры самостоятельно, или может использовать генератор параметра алгоритма, чтобы генерировать их, когда это может или, возможно, не инициализирует генератор параметра алгоритма с источником случайности.

Генераторы Параметра алгоритма и Параметры Алгоритма

Генератор параметра алгоритма engineGenerateParameters метод должен возвратиться AlgorithmParameters экземпляр.

Подпись и Алгоритмы Генерации Пары ключей или Ключевые Фабрики

Если Вы реализуете алгоритм подписи, Ваша реализация engineInitSign и engineInitVerify методы потребуют, передал - в ключах, которые допустимы для базового алгоритма (например, ключи DSA для алгоритма DSS). Можно сделать одно из следующего:

  1. Также создайте свои собственные классы, реализовывая соответствующие интерфейсы (например, классы, реализовывая DSAPrivateKey и DSAPublicKey интерфейсы от пакета java.security.interfaces), и создайте свой собственный генератор пары ключей и/или ключевые ключи возврата фабрики тех типов. Потребуйте ключей, к которым передают engineInitSign и engineInitVerify чтобы быть типами ключей, Вы реализовали, то есть, ключи, сгенерированные от Вашего генератора пары ключей или ключевой фабрики. Или Вы можете,
  2. Примите ключи от других генераторов пары ключей или других ключевых фабрик, пока они - экземпляры соответствующих интерфейсов, которые позволяют Вашей реализации подписи получить информацию, в которой она нуждается (такие как закрытые и открытые ключи и основные параметры). Например, engineInitSign метод для Подписи DSS, class мог принять любые закрытые ключи, которые являются экземплярами java.security.interfaces.DSAPrivateKey.

KeyStores и Фабрики Ключа и Сертификата

keystore реализация будет часто использовать ключевую фабрику, чтобы проанализировать ключи, сохраненные в keystore, и фабрике сертификата, чтобы проанализировать сертификаты, сохраненные в keystore.

Инициализации значения по умолчанию

В случае, если клиент явно не инициализирует генератор пары ключей или генератор параметра алгоритма, каждый провайдер такой службы должен предоставить (и документ) инициализацию значения по умолчанию. Например, провайдер Sun использует размер модуля значения по умолчанию (сила) 1024 битов для генерации параметров DSA, и провайдер "SunJCE" использует размер модуля значения по умолчанию (размер ключа) 1024 битов для генерации параметров Diffie-Hellman.

Требования Параметра Генератора Пары ключей значения по умолчанию

Если Вы реализуете генератор пары ключей, Ваша реализация должна предоставить параметры значения по умолчанию, которые используются, когда клиенты не определяют параметры. Документация, которую Вы предоставляете (Шаг 11), должна утвердить, каковы параметры значения по умолчанию.

Например, генератор пары ключей DSA в провайдере солнца предоставляет ряд предварительно вычисленного p, q, и g значения по умолчанию для генерации 512, 768, и 1024-разрядные пары ключей. Следующий p, q, и g значения используются в качестве значений по умолчанию для генерации 1024-разрядных пар ключей DSA:

p = fd7f5381 1d751229 52df4a9c 2eece4e7 f611b752 3cef4400 c31e3f80
    b6512669 455d4022 51fb593d 8d58fabf c5f5ba30 f6cb9b55 6cd7813b
    801d346f f26660b7 6b9950a5 a49f9fe8 047b1022 c24fbba9 d7feb7c6
    1bf83b57 e7c6a8a6 150f04fb 83f6d3c5 1ec30235 54135a16 9132f675
    f3ae2b61 d72aeff2 2203199d d14801c7

q = 9760508f 15230bcc b292b982 a2eb840b f0581cf5

g = f7e1a085 d69b3dde cbbcab5c 36b857b9 7994afbb fa3aea82 f9574c0b
    3d078267 5159578e bad4594f e6710710 8180b449 167123e8 4c281613
    b7cf0932 8cc8a6e1 3c167a8b 547c8d28 e0a3ae1e 2bb3a675 916ea37f
    0bfa2135 62f1fb62 7a01243b cca4f1be a8519089 a883dfe1 5ae59f06
    928b665e 807b5525 64014c3b fecf492a

( p и q значения, данные здесь, были сгенерированы главным стандартом генерации, используя 160-разрядное

SEED:  8d515589 4229d5e6 89ee01e6 018a237e 2cae64cd

С этим семенем находится алгоритм p и q когда счетчик был в 92.)

Provider.Service Класс

Начиная с его введения поставщики систем обеспечения безопасности опубликовали свою информацию о службе через соответственно отформатированных Строковых пар значения ключа, они вставляют свои записи Хеш-таблицы. В то время как этот механизм прост и удобен, он ограничивает возможную настройку количества. В результате JDK 5.0 представлял вторую опцию, Provider.Service class. Это предлагает альтернативный путь к провайдерам, чтобы рекламировать их службы и поддерживает дополнительные функции как описано ниже. Отметьте, что это дополнение является полностью совместимым с более старым методом использования Строки оцененные записи Хеш-таблицы. Провайдер на JDK 5.0 может выбрать или метод, как это предпочитает, или даже используйте обоих одновременно.

A Provider.Service объект инкапсулирует всю информацию о службе. Это - провайдер, который предлагает услугу, ее тип (например. MessageDigest или Signature), имя алгоритма, и имя class, который реализует службу. Дополнительно, это также включает список альтернативных имен алгоритма для этой службы (псевдонимы) и атрибуты, которые являются картой (имя, значение) Строковые пары. Кроме того, это определяет методы newInstance() и supportsParameter(). Они имеют реализации по умолчанию, но могут быть переопределены провайдерами если нужно, как может иметь место с провайдерами, которые взаимодействуют через интерфейс с маркерами аппаратного модуля безопасности.

newInstance() метод используется платформой безопасности, когда это должно создать новые экземпляры реализации. Реализация по умолчанию использует отражение, чтобы вызвать стандартного конструктора для соответствующего типа службы. Для всех стандартных служб кроме CertStore, это не-args конструктор. constructorParameter к newInstance() должен быть нуль в случаях тезисов. Для служб типа CertStore, конструктор, который берет a CertStoreParameters объект вызывается, и constructorParameter должен быть ненулевым экземпляром CertStoreParameters. Поставщик систем обеспечения безопасности может переопределить newInstance() метод, чтобы реализовать инстанцирование как соответствующий для той реализации. Это могло использовать прямой вызов или вызвать конструктора, который передает дополнительную информацию, определенную для экземпляра Провайдера или маркера. Например, если многократные читатели Смарт-карты присутствуют на системе, она могла бы передать информацию, о котором читателе недавно создаваемая служба должна быть связана с. Однако, несмотря на настройку все реализации должны следовать за соглашениями о constructorParameter, описанном выше.

supportsParameter() тесты, может ли Служба использовать указанный параметр. Это возвращает false, если эта служба не может использовать параметр. Это возвращает true, если эта служба может использовать параметр, если быстрый тест неосуществим, или если состояние неизвестно. Это используется платформой безопасности с некоторыми типами служб, чтобы быстро исключить несоответствие реализаций из рассмотрения. Это в настоящий момент только определяется для следующих стандартных служб: Signature, Cipher, Mac, и KeyAgreement. parameter должен быть экземпляром Key в этих случаях. Например, для Signature службы, платформа тестирует, может ли служба использовать предоставленный Ключ прежде, чем инстанцировать службы. Реализация по умолчанию исследует атрибуты SupportedKeyFormats и SupportedKeyClasses как описано ниже. Снова, провайдер может переопределить это методы, чтобы реализовать дополнительные тесты.

SupportedKeyFormats атрибут является списком поддерживаемых форматов для закодированных ключей (как возвращено key.getFormat()) разделенный "|" (канал) символ. Например, X.509|PKCS#8. SupportedKeyClasses атрибут является списком имен классов интерфейсов, разделенных "|" символ. Ключевой объект, как полагают, является приемлемым, если это присваиваемо по крайней мере одному из тех классов или названных интерфейсов. Другими словами, если class ключевого объекта является подклассом одного из перечисленных классов (или class непосредственно) или если это реализует перечисленный интерфейс. Значение в качестве примера "java.security.interfaces.RSAPrivateKey|java.security.interfaces.RSAPublicKey" .

Четыре метода были добавлены к Провайдеру class для добавления и поиска Служб. Как отмечалось ранее реализация тех методов и также существующих методов Properties была специально предназначена, чтобы гарантировать совместимость существующими подклассами Провайдера. Это достигается следующим образом:

Если методы Properties наследства используются, чтобы добавить записи, Провайдер, class удостоверяется, что строки свойства анализируются в эквивалентные объекты Службы до поиска через getService(). Точно так же, если метод putService() используется, эквивалентные строки свойства помещаются в хеш-таблицу провайдера одновременно. Если реализация провайдера переопределяет какой-либо из методов в Провайдере class, это должно гарантировать, что его реализация не вмешивается в это преобразование. Чтобы избежать проблем, мы рекомендуем, чтобы реализации не переопределили ни одного из методов в Provider class.

Форматы подписи

Если Вы реализуете алгоритм подписи, документация, которую Вы предоставляете (Шаг 11), должна определить формат в который подпись (сгенерированный одним из sign методы), кодируется.

Например, алгоритм подписи SHA1withDSA, предоставленный провайдером Sun, кодирует подпись как стандартную последовательность ASN.1 два ASN.1 INTEGER значения: r и s, в том порядке:

SEQUENCE ::= {
        r INTEGER,
        s INTEGER }

Интерфейсы DSA и их Необходимые Реализации

API Безопасности Java содержит следующие интерфейсы (в java.security.interfaces пакет) для удобства программистов, реализующих службы DSA:

Следующие разделы обсуждают требования для реализаций этих интерфейсов.

DSAKeyPairGenerator Реализация

Этот интерфейс является устаревшим. Это имело обыкновение быть необходимым, чтобы позволить клиентам обеспечить специфичные для DSA параметры, которые будут использоваться, а не параметры значения по умолчанию Ваши предоставления реализации. Однако, в Java это больше не необходимо; новое KeyPairGenerator initialize метод, который берет AlgorithmParameterSpec параметр позволяет клиентам указать на специфичные для алгоритма параметры.

DSAParams Реализация

Если Вы реализуете генератор пары ключей DSA, Вы нуждаетесь в реализации class DSAParams для содержания и возврата p, q, и g параметры.

A DSAParams реализация также требуется, если Вы реализуете DSAPrivateKey и DSAPublicKey интерфейсы. DSAPublicKey и DSAPrivateKey оба расширяют интерфейс DSAKey, который содержит a getParams метод, который должен возвратить a DSAParams объект. См. Реализации DSAPrivateKey и DSAPublicKey для получения дополнительной информации.

Отметьте: есть a DSAParams реализация встраивала в JDK: java.security.spec.DSAParameterSpec class.

DSAPrivateKey и DSAPublicKey Реализации

Если Вы реализуете генератор пары ключей DSA или ключевую фабрику, Вы должны создать классы, реализовывая DSAPrivateKey и DSAPublicKey интерфейсы.

Если Вы реализуете генератор пары ключей DSA, Ваш generateKeyPair метод (в Вашем KeyPairGeneratorSpi подкласс), возвратит экземпляры Ваших реализаций тех интерфейсов.

Если Вы реализуете ключевую фабрику DSA, Ваш engineGeneratePrivate метод (в Вашем KeyFactorySpi подкласс), возвратит экземпляр Вашего DSAPrivateKey реализация, и Ваш engineGeneratePublic метод возвратит экземпляр Вашего DSAPublicKey реализация.

Кроме того, Ваш engineGetKeySpec и engineTranslateKey методы будут ожидать, что переданным - в ключе будет экземпляр a DSAPrivateKey или DSAPublicKey реализация. getParams метод, обеспеченный реализациями интерфейса, полезен для получения и извлечения параметров от ключей и затем использования параметров, например как параметры к DSAParameterSpec конструктор вызывал, чтобы создать спецификацию параметра из значений параметра, которые могли использоваться, чтобы инициализировать a KeyPairGenerator объект для DSA.

Если Вы реализуете алгоритм подписи DSA, Ваш engineInitSign метод (в Вашем SignatureSpi подкласс), будет ожидать быть переданным a DSAPrivateKey и Ваш engineInitVerify метод будет ожидать быть переданным a DSAPublicKey.

Пожалуйста, отметьте: DSAPublicKey и DSAPrivateKey интерфейсы определяют очень универсальный, независимый от провайдера интерфейс к DSA открытые и закрытые ключи, соответственно. engineGetKeySpec и engineTranslateKey методы (в Вашем KeyFactorySpi подкласс), мог дополнительно проверить, является ли переданным - в ключе фактически экземпляр собственной реализации их провайдера DSAPrivateKey или DSAPublicKey, например, чтобы использовать в своих интересах специфичные для провайдера детали реализации. То же самое является истиной для алгоритма подписи DSA engineInitSign и engineInitVerify методы (в Вашем SignatureSpi подкласс).

Видеть, какие методы должны быть реализованы классами, которые реализуют DSAPublicKey и DSAPrivateKey интерфейсы, сначала отметьте следующие подписи интерфейса:

В java.security.interfaces пакет:

   public interface DSAPrivateKey extends DSAKey,
                java.security.PrivateKey

   public interface DSAPublicKey extends DSAKey,
                java.security.PublicKey

   public interface DSAKey 

В java.security пакет:

   public interface PrivateKey extends Key

   public interface PublicKey extends Key

   public interface Key extends java.io.Serializable 

Чтобы реализовать DSAPrivateKey и DSAPublicKey интерфейсы, следует реализовать методы, которые они определяют так же как определенные интерфейсами, которые они расширяют, прямо или косвенно.

Таким образом, для закрытых ключей, Вы должны предоставить class, который реализует

Интерфейсы RSA и их Необходимые Реализации

API Безопасности Java содержит следующие интерфейсы (в java.security.interfaces пакет) для удобства программистов, реализующих службы RSA:

Следующие разделы обсуждают требования для реализаций этих интерфейсов.

RSAPrivateKey , RSAPrivateCrtKey , и RSAPublicKey Реализации

Если Вы реализуете генератор пары ключей RSA или ключевую фабрику, Вы должны создать классы, реализовывая RSAPrivateKey (и/или RSAPrivateCrtKey) и RSAPublicKey интерфейсы. (RSAPrivateCrtKey интерфейс к закрытому ключу RSA, используя китайскую Теорему Остатка (CRT) представление.)

Если Вы реализуете генератор пары ключей RSA, Ваш generateKeyPair метод (в Вашем KeyPairGeneratorSpi подкласс), возвратит экземпляры Ваших реализаций тех интерфейсов.

Если Вы реализуете фабрику ключа RSA, Ваш engineGeneratePrivate метод (в Вашем KeyFactorySpi подкласс), возвратит экземпляр Вашего RSAPrivateKey (или RSAPrivateCrtKey) реализация, и Ваш engineGeneratePublic метод возвратит экземпляр Вашего RSAPublicKey реализация.

Кроме того, Ваш engineGetKeySpec и engineTranslateKey методы будут ожидать, что переданным - в ключе будет экземпляр RSAPrivateKey, RSAPrivateCrtKey, или RSAPublicKey реализация.

Если Вы реализуете алгоритм подписи RSA, Ваш engineInitSign метод (в Вашем SignatureSpi подкласс), будет ожидать быть переданным любой RSAPrivateKey или RSAPrivateCrtKey, и Ваш engineInitVerify метод будет ожидать быть переданным RSAPublicKey.

Пожалуйста, отметьте: RSAPublicKey, RSAPrivateKey, и RSAPrivateCrtKey интерфейсы определяют очень универсальный, независимый от провайдера интерфейс к открытым и закрытым ключам RSA. engineGetKeySpec и engineTranslateKey методы (в Вашем KeyFactorySpi подкласс), мог дополнительно проверить, является ли переданным - в ключе фактически экземпляр собственной реализации их провайдера RSAPrivateKey, RSAPrivateCrtKey, или RSAPublicKey, например, чтобы использовать в своих интересах специфичные для провайдера детали реализации. То же самое является истиной для алгоритма подписи RSA engineInitSign и engineInitVerify методы (в Вашем SignatureSpi подкласс).

Видеть, какие методы должны быть реализованы классами, которые реализуют RSAPublicKey, RSAPrivateKey, и RSAPrivateCrtKey интерфейсы, сначала отметьте следующие подписи интерфейса:

В java.security.interfaces пакет:

    public interface RSAPrivateKey extends java.security.PrivateKey

    public interface RSAPrivateCrtKey extends RSAPrivateKey

    public interface RSAPublicKey extends java.security.PublicKey

В java.security пакет:

    public interface PrivateKey extends Key

    public interface PublicKey extends Key

    public interface Key extends java.io.Serializable

Чтобы реализовать RSAPrivateKey, RSAPrivateCrtKey, и RSAPublicKey интерфейсы, следует реализовать методы, которые они определяют так же как определенные интерфейсами, которые они расширяют, прямо или косвенно.

Таким образом, для закрытых ключей RSA, Вы должны предоставить class, который реализует:

Точно так же для закрытых ключей RSA, используя китайскую Теорему Остатка (CRT) представление, Вы должны предоставить class, который реализует:

Для общедоступных ключей RSA Вы должны предоставить class, который реализует:

JCA содержит много AlgorithmParameterSpec реализации для наиболее часто используемого шифра и параметров алгоритма согласования ключей. Если Вы будете работать на параметрах алгоритма, которые должны быть для различного типа алгоритма, не обеспеченного JCA, то Вы должны будете предоставить свое собственное AlgorithmParameterSpec реализация, подходящая для того типа алгоритма.

Интерфейсы Diffie-Hellman и их Необходимые Реализации

JCA содержит следующие интерфейсы (в javax.crypto.interfaces пакет) для удобства программистов, реализующих службы Diffie-Hellman:

Следующие разделы обсуждают требования для реализаций этих интерфейсов.

DHPrivateKey и DHPublicKey Реализации

Если Вы реализуете генератор пары ключей Diffie-Hellman или ключевую фабрику, Вы должны создать классы, реализовывая DHPrivateKey и DHPublicKey интерфейсы.

Если Вы реализуете генератор пары ключей Diffie-Hellman, Ваш generateKeyPair метод (в Вашем KeyPairGeneratorSpi подкласс), возвратит экземпляры Ваших реализаций тех интерфейсов.

Если Вы реализуете фабрику ключа Diffie-Hellman, Ваш engineGeneratePrivate метод (в Вашем KeyFactorySpi подкласс), возвратит экземпляр Вашего DHPrivateKey реализация, и Ваш engineGeneratePublic метод возвратит экземпляр Вашего DHPublicKey реализация.

Кроме того, Ваш engineGetKeySpec и engineTranslateKey методы будут ожидать, что переданным - в ключе будет экземпляр a DHPrivateKey или DHPublicKey реализация. getParams метод, обеспеченный реализациями интерфейса, полезен для получения и извлечения параметров от ключей. Можно тогда использовать параметры, например, как параметры к DHParameterSpec конструктор вызывал, чтобы создать спецификацию параметра из значений параметра, используемых, чтобы инициализировать a KeyPairGenerator объект для Diffie-Hellman.

Если Вы реализуете алгоритм согласования ключей Diffie-Hellman, Ваш engineInit метод (в Вашем KeyAgreementSpi подкласс), будет ожидать быть переданным a DHPrivateKey и Ваш engineDoPhase метод будет ожидать быть переданным a DHPublicKey.

Отметьте: DHPublicKey и DHPrivateKey интерфейсы определяют очень универсальный, независимый от провайдера интерфейс к открытым и закрытым ключам Diffie-Hellman, соответственно. engineGetKeySpec и engineTranslateKey методы (в Вашем KeyFactorySpi подкласс), мог дополнительно проверить, является ли переданным - в ключе фактически экземпляр собственной реализации их провайдера DHPrivateKey или DHPublicKey, например, чтобы использовать в своих интересах специфичные для провайдера детали реализации. То же самое является истиной для алгоритма Diffie-Hellman engineInit и engineDoPhase методы (в Вашем KeyAgreementSpi подкласс).

Видеть, какие методы должны быть реализованы классами, которые реализуют DHPublicKey и DHPrivateKey интерфейсы, сначала отметьте следующие подписи интерфейса:

В javax.crypto.interfaces пакет:

    public interface DHPrivateKey extends DHKey, java.security.PrivateKey

    public interface DHPublicKey extends DHKey, java.security.PublicKey

    public interface DHKey 

В java.security пакет:

    public interface PrivateKey extends Key

    public interface PublicKey extends Key

    public interface Key extends java.io.Serializable 

Реализовывать DHPrivateKey и DHPublicKey интерфейсы, следует реализовать методы, которые они определяют так же как определенные интерфейсами, которые они расширяют, прямо или косвенно.

Таким образом, для закрытых ключей, Вы должны предоставить class, который реализует:

  • getX метод от DHPrivateKey интерфейс.
  • getParams метод от javax.crypto.interfaces. Интерфейс DHKey, с тех пор DHPrivateKey расширяется DHKey.
  • getAlgorithm, getEncoded, и getFormat методы от java.security. Ключевой интерфейс, с тех пор DHPrivateKey расширяется java.security.PrivateKey, и PrivateKey расширяется Key.

Точно так же для общедоступных ключей Diffie-Hellman, Вы должны предоставить class, который реализует:

  • getY метод от DHPublicKey интерфейс.
  • getParams метод от javax.crypto.interfaces.DHKey интерфейс, с тех пор DHPublicKey расширяется DHKey.
  • getAlgorithm, getEncoded, и getFormat методы от java.security. Ключевой интерфейс, с тех пор DHPublicKey расширяется java.security.PublicKey, и PublicKey расширяется Key.

Интерфейсы для Других Типов Алгоритма

Как отмечено выше, API Безопасности Java содержит интерфейсы для удобства служб реализации программистов как DSA, RSA и ECC. Если есть службы без поддержки API, Вы должны определить свои собственные API.

Если Вы реализуете генератор пары ключей для различного алгоритма, следует создать интерфейс с один или больше initialize методы, которые могут вызвать клиенты, когда они хотят обеспечить специфичные для алгоритма параметры, которые будут использоваться, а не параметры значения по умолчанию Ваши предоставления реализации. Ваш подкласс KeyPairGeneratorSpi должен реализовать этот интерфейс.

Для алгоритмов без прямой поддержки API рекомендуется, чтобы Вы создали подобные интерфейсы и обеспечили классы реализации. Ваш интерфейс с открытым ключом должен расшириться PublicKey интерфейс. Точно так же Ваш интерфейс с закрытым ключом должен расшириться PrivateKey интерфейс.

Интерфейсы Спецификации Параметра алгоритма и Классы

Спецификация параметра алгоритма является прозрачным представлением наборов параметров, используемых с алгоритмом.

Прозрачное представление параметров означает, что можно получить доступ к каждому значению индивидуально через один из получить методов, определенных в соответствующей спецификации class (например, DSAParameterSpec определяет getP, getQ, и getG методы, чтобы получить доступ к p, q, и параметрам г, соответственно).

Это противопоставляется с непрозрачным представлением, как предоставлено механизмом AlgorithmParameters class, в котором у Вас нет никакого прямого доступа к ключевым материальным ценностям; можно только получить имя алгоритма, связанного с набором параметра (через getAlgorithm) и некоторое кодирование для набора параметра (через getEncoded).

Если Вы предоставляете AlgorithmParametersSpi, AlgorithmParameterGeneratorSpi, или KeyPairGeneratorSpi реализация, следует использовать AlgorithmParameterSpec интерфейс, начиная с каждого из тех классов содержат методы, которые берут AlgorithmParameterSpec параметр. Такие методы должны определить, в какой фактической реализации того интерфейса передали, и действует соответственно.

JCA содержит много AlgorithmParameterSpec реализации для наиболее часто используемой подписи, шифра и параметров алгоритма согласования ключей. Если Вы будете работать на параметрах алгоритма, которые должны быть для различного типа алгоритма, не обеспеченного JCA, то Вы должны будете предоставить свое собственное AlgorithmParameterSpec реализация, подходящая для того типа алгоритма.

Java определяет следующие интерфейсы спецификации параметра алгоритма и классы в java.security.spec и javax.crypto.spec пакеты:

AlgorithmParameterSpec Интерфейс

AlgorithmParameterSpec интерфейс к прозрачной спецификации криптографических параметров.

Этот интерфейс не содержит методов или констант. Его единственная цель состоит в том, чтобы сгруппировать (и обеспечить безопасность типов для), все спецификации параметра. Все спецификации параметра должны реализовать этот интерфейс.

DSAParameterSpec Класс

Этот class (который реализует AlgorithmParameterSpec и DSAParams интерфейсы), определяет набор параметров, используемых с алгоритмом DSA. У этого есть следующие методы:

    public BigInteger getP()

    public BigInteger getQ()

    public BigInteger getG()

Эти методы возвращают параметры алгоритма DSA: начало p, субстандартное q, и основа g.

Много типов служб DSA сочтут этот class полезным - например, он используется подписью DSA, генератором пары ключей, генератором параметра алгоритма, и классами параметров алгоритма, реализованными провайдером Sun. Как определенный пример, реализация параметров алгоритма должна включать реализацию для getParameterSpec метод, который возвращается AlgorithmParameterSpec. Реализация параметров алгоритма DSA, предоставленная Sun, возвращает экземпляр DSAParameterSpec class.

IvParameterSpec Класс

Этот class (который реализует AlgorithmParameterSpec интерфейс), определяет вектор инициализации (IV) используемый с шифром в режиме обратной связи.

Метод в IvParameterSpec
Метод Описание
byte[] getIV() Возвращает вектор инициализации (IV).

OAEPParameterSpec Класс

Этот class определяет набор параметров, используемых с Дополнением OAEP, как определено в PKCS #1 стандарт.

Методы в OAEPParameterSpec
Метод Описание
String getDigestAlgorithm() Возвращает имя алгоритма обзора сообщения.
String getMGFAlgorithm() Возвращает имя алгоритма функции генерации маски.
AlgorithmParameterSpec getMGFParameters() Возвращает параметры для функции генерации маски.
PSource getPSource() Возвращает источник кодирования ввода P.

PBEParameterSpec Класс

Этот class (который реализует AlgorithmParameterSpec интерфейс), определяет набор параметров, используемых с основанным на пароле шифрованием (PBE) алгоритм.

Методы в PBEParameterSpec
Метод Описание
int getIterationCount() Возвращает итеративное количество.
byte[] getSalt() Возвращает соль.

RC2ParameterSpec Класс

Этот class (который реализует AlgorithmParameterSpec интерфейс), определяет набор параметров, используемых с алгоритмом RC2.

Методы в RC2ParameterSpec
Метод Описание
boolean equals(Object obj) Тесты для равенства между указанным объектом и этим объектом.
int getEffectiveKeyBits() Возвращает эффективный размер ключа в битах.
byte[] getIV() Возвращает IV или нуль, если этот набор параметра не содержит IV.
int hashCode() Вычисляет значение хэш-кода для объекта.

RC5ParameterSpec Класс

Этот class (который реализует AlgorithmParameterSpec интерфейс), определяет набор параметров, используемых с алгоритмом RC5.

Методы в RC5ParameterSpec
Метод Описание
boolean equals(Object obj) Тесты для равенства между указанным объектом и этим объектом.
byte[] getIV() Возвращает IV или нуль, если этот набор параметра не содержит IV.
int getRounds() Возвращает число раундов.
int getVersion() Возвращает версию.
int getWordSize() Возвращает размер слова в битах.
int hashCode() Вычисляет значение хэш-кода для объекта.

DHParameterSpec Класс

Этот class (который реализует AlgorithmParameterSpec интерфейс), определяет набор параметров, используемых с алгоритмом Diffie-Hellman.

Методы в DHParameterSpec
Метод Описание
BigInteger getG() Возвращает основной генератор g.
int getL() Возвращает размер в битах, l, из случайной экспоненты (частное значение).
BigInteger getP() Возвращает главный модуль p.

Много типов служб Diffie-Hellman сочтут этот class полезным; например, это используется согласованием ключей Diffie-Hellman, генератором пары ключей, генератором параметра алгоритма, и классами параметров алгоритма, реализованными провайдером "SunJCE". Как определенный пример, реализация параметров алгоритма должна включать реализацию для getParameterSpec метод, который возвращается AlgorithmParameterSpec. Реализация параметров алгоритма Diffie-Hellman, предоставленная "SunJCE", возвращает экземпляр DHParameterSpec class.

Ключевые Интерфейсы Спецификации и Классы, Необходимые Ключевыми Фабриками

Ключевая фабрика обеспечивает двунаправленные преобразования между непрозрачными ключами (типа Key) и ключевые спецификации. Если Вы реализуете ключевую фабрику, Вы таким образом должны понять и использовать ключевые спецификации. В некоторых случаях Вы также должны реализовать свои собственные ключевые спецификации.

Дополнительная информация о ключевых спецификациях, интерфейсах и классах, предоставленных в Java, и ключевых требованиях фабрики относительно спецификаций, обеспечивается ниже.

Ключевые спецификации являются прозрачными представлениями ключевого материала, который составляет ключ. Если ключ сохранен на устройстве, его спецификация может содержать информацию, которая помогает идентифицировать ключ на устройстве.

Прозрачное представление ключей означает, что можно получить доступ к каждой ключевой материальной ценности индивидуально через один из получить методов, определенных в соответствующей спецификации class. Например, java.security.spec.DSAPrivateKeySpec определяет getX, getP, getQ, и getG методы, чтобы получить доступ к закрытому ключу x, и параметры алгоритма DSA, используемые, чтобы вычислить ключ: начало p, субстандартное q, и основа g.

Это противопоставляется с непрозрачным представлением, как определено Ключевым интерфейсом, в котором у Вас нет никакого прямого доступа к полям параметра. Другими словами "непрозрачное" представление дает Вам ограниченный доступ к ключу - только эти три метода, определенные Ключевым интерфейсом: getAlgorithm, getFormat, и getEncoded.

Ключ может быть определен специфичным для алгоритма способом, или независимым от алгоритма форматом кодирования (таким как ASN.1). Например, закрытый ключ DSA может быть определен его компонентами x, p, q, и g (см. DSAPrivateKeySpec), или это может быть определено, используя его DER, кодирующий (см. PKCS8EncodedKeySpec).

Java определяет следующие ключевые интерфейсы спецификации и классы в java.security.spec и javax.crypto.spec пакеты:

KeySpec Интерфейс

Этот интерфейс не содержит методов или констант. Его единственная цель состоит в том, чтобы сгруппировать (и обеспечить безопасность типов для), все ключевые спецификации. Все ключевые спецификации должны реализовать этот интерфейс.

Java предоставляет несколько классов, реализовывая KeySpec интерфейс: DSAPrivateKeySpec, DSAPublicKeySpec, RSAPrivateKeySpec, RSAPublicKeySpec, EncodedKeySpec, PKCS8EncodedKeySpec, и X509EncodedKeySpec.

Если Ваш провайдер использует ключевые типы (например, Your_PublicKey_type и Your_PrivateKey_type) для которого JDK уже не обеспечивает соответствующий KeySpec классы, есть два возможных сценария, один из которых требует, чтобы Вы реализовали свои собственные ключевые спецификации:

  1. Если Ваши пользователи никогда не должны будут получать доступ к определенным ключевым материальным ценностям Вашего ключевого типа, Вы не должны будете предоставить никому KeySpec классы для Вашего ключевого типа.

    В этом сценарии Ваши пользователи будут всегда создавать Your_PublicKey_type и Your_PrivateKey_type ключи через соответствующее KeyPairGenerator предоставленный Вашим провайдером для того ключевого типа. Если они хотят сохранить сгенерированные ключи для более позднего использования, они получают кодировки ключей (использующий getEncoded метод Key интерфейс). Когда они хотят создать Your_PublicKey_type или Your_PrivateKey_type ключ от кодирования (например, чтобы инициализировать Подпись, возражают для подписания или проверки), они создают экземпляр X509EncodedKeySpec или PKCS8EncodedKeySpec от кодирования, и канала это к соответствующему KeyFactory предоставленный Вашим провайдером для того алгоритма, чей generatePublic и generatePrivate методы возвратят требуемый PublicKey (экземпляр Your_PublicKey_type) или PrivateKey (экземпляр Your_PrivateKey_type) объект, соответственно.
  2. Если Вы ожидаете потребность в пользователях получить доступ к определенным ключевым материальным ценностям Вашего ключевого типа, или создать ключ Вашего ключевого типа от ключевых материальных и связанных значений параметра, а не от его кодирования (как в вышеупомянутом случае), необходимо определить новый KeySpec классы (классы, которые реализуют KeySpec интерфейс) с соответствующими методами конструктора и получают методы для того, чтобы они возвратили ключевые материальные поля и связанные значения параметра для Вашего ключевого типа. Вы определите те классы подобным образом, как делается DSAPrivateKeySpec и DSAPublicKeySpec классы, обеспеченные в JDK 6. Вы должны поставить те классы наряду со своими классами провайдера, например, как часть Вашего файла JAR провайдера.

DSAPrivateKeySpec Класс

Этот class (который реализует KeySpec Интерфейс), определяет закрытый ключ DSA с его связанными параметрами. У этого есть следующие методы:

Метод в DSAPrivateKeySpec Описание
public BigInteger getX() Возвращает закрытый ключ x.
public BigInteger getP() Возвращает главный p.
public BigInteger getQ() Возвращает субстандартный q.
public BigInteger getG() Возвращает основной г.

Эти методы возвращают закрытый ключ x, и параметры алгоритма DSA, используемые, чтобы вычислить ключ: начало p, субстандартное q, и основа g.

Класс DSAPublicKeySpec

Этот class (который реализует KeySpec Интерфейс), определяет открытый ключ DSA с его связанными параметрами. У этого есть следующие методы:

Метод в DSAPublicKeySpec Описание
public BigInteger getY() возвращает открытый ключ y.
public BigInteger getP() Возвращает главный p.
public BigInteger getQ() Возвращает субстандартный q.
public BigInteger getG() Возвращает основной г.

Эти методы возвращают открытый ключ y, и параметры алгоритма DSA, используемые, чтобы вычислить ключ: начало p, субстандартное q, и основа g.

Класс RSAPrivateKeySpec

Этот class (который реализует KeySpec Интерфейс), определяет закрытый ключ RSA. У этого есть следующие методы:

Метод в RSAPrivateKeySpec Описание
public BigInteger getModulus() Возвращает модуль.
public BigInteger getPrivateExponent() Возвращает частную экспоненту.

Эти методы возвращают модуль RSA n и частная экспонента d значения, которые составляют закрытый ключ RSA.

Класс RSAPrivateCrtKeySpec

Этот class (который расширяется RSAPrivateKeySpec class), определяет закрытый ключ RSA, как определено в PKCS#1 стандарт, используя китайскую Теорему Остатка (CRT) информационные значения. У этого есть следующие методы (в дополнение к методам, наследованным от его суперкласса RSAPrivateKeySpec ):

Метод в RSAPrivateCrtKeySpec Описание
public BigInteger getPublicExponent() Возвращает общедоступную экспоненту.
public BigInteger getPrimeP() Возвращает главный P.
public BigInteger getPrimeQ() Возвращает главный Q.
public BigInteger getPrimeExponentP() Возвращает primeExponentP.
public BigInteger getPrimeExponentQ() Возвращает primeExponentQ.
public BigInteger getCrtCoefficient() Возвращает crtCoefficient.

Эти методы возвращают общедоступную экспоненту e и целые числа информации о CRT: простой множитель p из модуля n, простой множитель q из n, экспонента d mod (p-1), экспонента d mod (q-1), и китайский коэффициент Теоремы Остатка (inverse of q) mod p.

Закрытый ключ RSA логически состоит из только модуля и частной экспоненты. Присутствие значений CRT предназначается для эффективности.

Класс RSAPublicKeySpec

Этот class (который реализует KeySpec Интерфейс), определяет открытый ключ RSA. У этого есть следующие методы:

Метод в RSAPublicKeySpec Описание
public BigInteger getModulus() Возвращает модуль.
public BigInteger getPublicExponent() Возвращает общедоступную экспоненту.

Эти методы возвращают модуль RSA n и общедоступная экспонента e значения, которые составляют открытый ключ RSA.

Класс EncodedKeySpec

Этот абстрактный class (который реализует KeySpec Интерфейс), представляет или закрытый ключ с открытым ключом в закодированном формате.

Метод в EncodedKeySpec Описание
public abstract byte[] getEncoded() Возвращает закодированный ключ.
public abstract String getFormat() Возвращает имя формата кодирования.

JDK 6 предоставлений два класса, реализовывая EncodedKeySpec интерфейс: PKCS8EncodedKeySpec и X509EncodedKeySpec. При желании можно предоставить свое собственное EncodedKeySpec реализации для тех или других типов ключевых кодировок.

PKCS8EncodedKeySpec Класс

Этот class, который является подклассом EncodedKeySpec, представляет кодирование DER закрытого ключа, согласно формату, определенному в PKCS #8 стандарт.

getEncoded метод возвращает ключевые байты, закодированные согласно PKCS #8 стандарт. getFormat метод возвращает строку "PKCS#8".

Класс X509EncodedKeySpec

Этот class, который является подклассом EncodedKeySpec, представляет кодирование DER или закрытого ключа с открытым ключом, согласно формату, определенному в стандарте X.509.

getEncoded метод возвращает ключевые байты, закодированные согласно стандарту X.509. getFormat метод возвращает строку "X.509". DHPrivateKeySpec, DHPublicKeySpec, DESKeySpec, DESedeKeySpec, PBEKeySpec, и SecretKeySpec.

DHPrivateKeySpec Класс

Этот class (который реализует KeySpec интерфейс), определяет закрытый ключ Diffie-Hellman с его связанными параметрами.

Метод в DHPrivateKeySpec Описание
BigInteger getG() Возвращает основной генератор g.
BigInteger getP() Возвращает главный модуль p.
BigInteger getX() Возвращает частное значение x.

DHPublicKeySpec Класс

Этот class (который реализует KeySpec интерфейс), определяет открытый ключ Diffie-Hellman с его связанными параметрами.

Метод в DHPublicKeySpec Описание
BigInteger getG() Возвращает основной генератор g.
BigInteger getP() Возвращает главный модуль p.
BigInteger getY() Возвращает общедоступное значение y.

DESKeySpec Класс

Этот class (который реализует KeySpec интерфейс), определяет ключ DES.

Метод в DESKeySpec Описание
byte[] getKey() Возвращает ключевые байты DES.
static boolean isParityAdjusted(byte[] key, int offset) Проверки, если данный ключевой материал DES скорректирован четностью.
static boolean isWeak(byte[] key, int offset) Проверки, если данный ключевой материал DES слаб или полуслаб.

DESedeKeySpec Класс

Этот class (который реализует KeySpec интерфейс), определяет ЭДЕ DES (Тройной DES) ключ.

Метод в DESedeKeySpec Описание
byte[] getKey() Возвращает ключ ЭДЕ DES.
static boolean isParityAdjusted(byte[] key, int offset) Проверки, если данный ключ ЭДЕ DES скорректирован четностью.

PBEKeySpec Класс

Этот class реализует KeySpec интерфейс. Выбранный пользователем пароль может использоваться с основанным на пароле шифрованием (PBE); пароль может быть просмотрен как тип необработанного ключевого материала. Механизм шифрования, который использует этот class, может получить криптографический ключ из необработанного ключевого материала.

Метод в PBEKeySpec Описание
void clearPassword Очищает внутреннюю копию пароля.
int getIterationCount Возвращает итеративное количество или 0 если не определенный.
int getKeyLength Возвращает будущим образом полученную длину ключа или 0 если не определенный.
char[] getPassword Возвращает копию пароля.
byte[] getSalt Возвращает копию соли или нуля если не определенный.

SecretKeySpec Класс

Этот class реализует KeySpec интерфейс. Так как это также реализует SecretKey интерфейс, это может использоваться, чтобы создать a SecretKey объект независимым от провайдера способом, то есть, не имея необходимость проходить через основанное на провайдере SecretKeyFactory.

Метод в SecretKeySpec Описание
boolean equals (Object obj) Указывает, " ли некоторый другой объект равен" этому.
String getAlgorithm() Возвращает имя алгоритма, связанного с этим секретным ключом.
byte[] getEncoded() Возвращает ключевой материал этого секретного ключа.
String getFormat() Возвращает имя формата кодирования для этого секретного ключа.
int hashCode() Вычисляет значение хэш-кода для объекта.

Генерация секретного ключа

Если Вы обеспечиваете генератор секретного ключа (подкласс javax.crypto.KeyGeneratorSpi) для определенного алгоритма секретного ключа можно возвратить сгенерированный объект секретного ключа (который должен быть экземпляром javax.crypto.SecretKey, см. engineGenerateKey) одним из следующих способов:

  • Вы реализуете class, экземпляры которого представляют секретные ключи алгоритма, связанного с Вашим ключевым генератором. Ваша ключевая реализация генератора возвращает экземпляры того class. Этот подход полезен, если у ключей, сгенерированных Вашим ключевым генератором, есть специфичные для провайдера свойства.
  • Ваш ключевой генератор возвращает экземпляр SecretKeySpec, который уже реализует javax.crypto.SecretKey интерфейс. Вы передаете (необработанные) ключевые байты и имя алгоритма секретного ключа, связанного с Вашим ключевым генератором с SecretKeySpec конструктор. Этот подход полезен, если базовые (необработанные) ключевые байты могут быть представлены как байтовый массив и не иметь никаких основных параметров, связанных с ними.

Добавление Новых Объектных Идентификаторов

Следующая информация применяется к провайдерам, кто предоставляет алгоритм, который не перечисляется как один из стандартных алгоритмов в Приложении A Справочника Архитектуры Криптографии Java.

Отображение от OID, чтобы Назвать

Иногда JCA должен инстанцировать реализации криптографического алгоритма от идентификатора алгоритма (например, как кодирующийся в сертификате), который по определению включает объектный идентификатор (OID) алгоритма. Например, чтобы проверить подпись на сертификате X.509, JCA определяет алгоритм подписи от идентификатора алгоритма подписи, который кодируется в сертификате, инстанцирует объекта Подписи для того алгоритма, и инициализирует объект Подписи для проверки.

Для JCA, чтобы найти Ваш алгоритм, следует обеспечить объектный идентификатор своего алгоритма как запись псевдонима для Вашего алгоритма в основном файле провайдера.

    put("Alg.Alias.<engine_type>.1.2.3.4.5.6.7.8",
        "<algorithm_alias_name>");

Отметьте, что, если Ваш алгоритм известен больше чем под одним объектным идентификатором, Вы должны создать запись псевдонима для каждого объектного идентификатора, под которым это известно.

Пример того, где JCA должен выполнить этот тип отображения, то, когда Ваш алгоритм ("Foo"), алгоритм подписи и пользователи, выполненные keytool команда и определяет Ваш (подпись) псевдоним алгоритма.

    % keytool -genkeypair -sigalg 1.2.3.4.5.6.7.8

В этом случае Ваш основной файл провайдера должен содержать следующие записи:

    put("Signature.Foo", "com.xyz.MyFooSignatureImpl");
    put("Alg.Alias.Signature.1.2.3.4.5.6.7.8", "Foo");

Другие примеры того, где этот тип отображения выполняется, (1), когда Ваш алгоритм является keytype алгоритмом, и Ваша программа анализирует сертификат (использующий реализацию X.509 провайдера SUN) и извлекает открытый ключ из сертификата, чтобы инициализировать объект Подписи для проверки, и (2) когда keytool пользователи пытаются получить доступ к закрытому ключу Вашего keytype (например, выполнить цифровую подпись) генерировав соответствующую пару ключей. В этих случаях Ваш основной файл провайдера должен содержать следующие записи:

    put("KeyFactory.Foo", "com.xyz.MyFooKeyFactoryImpl");
    put("Alg.Alias.KeyFactory.1.2.3.4.5.6.7.8", "Foo");

Отображение от Имени до OID

Если JCA должен выполнить обратное отображение (то есть, от Вашего имени алгоритма до его связанного OID), Вы должны обеспечить запись псевдонима следующей формы для одного из OID, под которыми должен быть известен Ваш алгоритм:

    put("Alg.Alias.Signature.OID.1.2.3.4.5.6.7.8", "MySigAlg");

Если Ваш алгоритм известен больше чем под одним объектным идентификатором, снабдите префиксом привилегированный "OID".

Пример того, где JCA должен выполнить этот вид отображения, то, когда выполненные пользователи keytool в любом режиме, который берет a -sigalg опция. Например, когда -genkeypair и -certreq команды вызываются, пользователь может определить Ваш (подпись) алгоритм с -sigalg опция.

Обеспечение Экс-мобильности

Главной особенностью JCA является экс-мобильность платформы JCA и реализаций криптографии провайдера, если определенные условия соблюдаются.

Должный импортировать ограничения управления правительствами нескольких стран, файлы политики юрисдикции, поставленные с JDK 6 из Sun Microsystems, определяют, что "strong", но ограниченная криптография может использоваться. "Неограниченная" версия этих файлов, не указывающих ни на какие ограничения на криптографические сильные места, доступна для тех, которые живут в имеющих право странах (который является большинством стран). Но только версия "strong" может быть импортирована в те страны, правительства которых передают под мандат ограничения. Платформа JCA осуществит ограничения, определенные в установленных файлах политики юрисдикции.

Как отмечено в другом месте, можно записать только одну версию своего программного обеспечения провайдера, реализовывая криптографию максимальной силы. Это до JCA, не Вашего провайдера, чтобы осуществить любую политику юрисдикции переданные под мандат файлом ограничения относительно криптографических алгоритмов и максимальных криптографических сильных мест, доступных апплетам/приложениям в различных расположениях.

Условия, которые должен соблюдать Ваш провайдер, чтобы позволить ему быть включенным JCA, являются следующим:

  • Конструктор каждой реализации SPI, class должен сделать проверку самоцелостности, как описано в том, Как Провайдер Может Сделать Проверку Самоцелостности.
  • Код провайдера должен быть записан таким способом, которым классы провайдера становятся неприменимыми если инстанцировано приложением непосредственно, обходя JCA. См. Шаг 1: Запишите Свой Код Реализации Службы в Шагах, чтобы Реализовать и Интегрировать раздел Провайдера.
  • Пакет провайдера должен быть подписан объектом, которому доверяет платформа JCA. (См. Шаг 6.1 через Шаг 6.2.) американские поставщики, провайдеры которых могут быть экспортированы вне США сначала, должны просить американское правительственное одобрение экспорта. (См. Шаг 10.)

Приложение A: Мастер класс Провайдера Sun

Ниже сокращенная версия Sun.java файл, который содержит названный class Sun это - основной class для провайдера под названием Sun.

Как со всеми мастер классами, этот class является подклассом Provider. Это определяет имена class и расположения пакета всех реализаций службы, предоставленных провайдером Sun. Эта информация используется getInstance методы классов механизма, чтобы искать различные алгоритмы и другие службы, когда их требуют.

Этот код предоставляется как пример ведущего устройства провайдера class.

/*
 * @(#)Sun.java 1.28 99/05/27
 *
 * Copyright (c) 1996, 1998, Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Oracle nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package sun.security.provider;

import java.io.*;
import java.util.*;
import java.security.*;

/**
 * The SUN Security Provider.
 *
 * @author Benjamin Renaud
 *
 * @version 1.28, 05/27/99
 */

/**
 * Defines the SUN provider.
 *
 * Algorithms supported, and their names:
 *
 * - SHA is the message digest scheme described in FIPS 180-1.
 *   Aliases for SHA are SHA-1 and SHA1.
 *
 * - SHA1withDSA is the signature scheme described in FIPS 186.
 *   (SHA used in DSA is SHA-1: FIPS 186 with Change No 1.)
 *   Aliases for SHA1withDSA are DSA, DSS, SHA/DSA, SHA-1/DSA, SHA1/DSA,
 *   SHAwithDSA, DSAWithSHA1, and the object
 *   identifier strings "OID.1.3.14.3.2.13", "OID.1.3.14.3.2.27" and
 *   "OID.1.2.840.10040.4.3".
 *
 * - DSA is the key generation scheme as described in FIPS 186.
 *   Aliases for DSA include the OID strings "OID.1.3.14.3.2.12"
 *   and "OID.1.2.840.10040.4.1".
 *
 * - MD5 is the message digest scheme described in RFC 1321.
 *   There are no aliases for MD5.
 */

public final class Sun extends Provider {

    private static final String INFO = "SUN " +
    "(DSA key/parameter generation; DSA signing; " +
    "SHA-1, MD5 digests; SecureRandom; X.509 certificates; JKS keystore)";

    public Sun() {
        /* We are the SUN provider */
        super("SUN", 1.2, INFO);

        AccessController.doPrivileged(new java.security.PrivilegedAction() {
            public Object run() {

                /*
                 * Signature engines
                 */
                put("Signature.SHA1withDSA", "sun.security.provider.DSA");

                put("Alg.Alias.Signature.DSA", "SHA1withDSA");
                put("Alg.Alias.Signature.DSS", "SHA1withDSA");
                put("Alg.Alias.Signature.SHA/DSA", "SHA1withDSA");
                put("Alg.Alias.Signature.SHA-1/DSA", "SHA1withDSA");
                put("Alg.Alias.Signature.SHA1/DSA", "SHA1withDSA");
                put("Alg.Alias.Signature.SHAwithDSA", "SHA1withDSA");
                put("Alg.Alias.Signature.DSAWithSHA1", "SHA1withDSA");
                put("Alg.Alias.Signature.OID.1.2.840.10040.4.3",
                    "SHA1withDSA");
                put("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA1withDSA");
                put("Alg.Alias.Signature.1.3.14.3.2.13", "SHA1withDSA");
                put("Alg.Alias.Signature.1.3.14.3.2.27", "SHA1withDSA");

                /*
                 *  Key Pair Generator engines
                 */
                put("KeyPairGenerator.DSA",
                    "sun.security.provider.DSAKeyPairGenerator");
                put("Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1", "DSA");
                put("Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1", "DSA");
                put("Alg.Alias.KeyPairGenerator.1.3.14.3.2.12", "DSA");

                /*
                 * Digest engines
                 */
                put("MessageDigest.MD5", "sun.security.provider.MD5");
                put("MessageDigest.SHA", "sun.security.provider.SHA");

                put("Alg.Alias.MessageDigest.SHA-1", "SHA");
                put("Alg.Alias.MessageDigest.SHA1", "SHA");

                /*
                 * Algorithm Parameter Generator engines
                 */
                put("AlgorithmParameterGenerator.DSA",
                    "sun.security.provider.DSAParameterGenerator");

                /*
                 * Algorithm Parameter engines
                 */
                put("AlgorithmParameters.DSA",
                    "sun.security.provider.DSAParameters");
                put("Alg.Alias.AlgorithmParameters.1.3.14.3.2.12", "DSA");
                put("Alg.Alias.AlgorithmParameters.1.2.840.10040.4.1", "DSA");

                /*
                 * Key factories
                 */
                put("KeyFactory.DSA", "sun.security.provider.DSAKeyFactory");
                put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSA");
                put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSA");

                /*
                 * SecureRandom
                 */
                 put("SecureRandom.SHA1PRNG",
                     "sun.security.provider.SecureRandom");

                /*
                 * Certificates
                 */
                put("CertificateFactory.X509",
                    "sun.security.provider.X509Factory");
                put("Alg.Alias.CertificateFactory.X.509", "X509");

                /*
                 * KeyStore
                 */
                put("KeyStore.JKS", "sun.security.provider.JavaKeyStore");

                /*
                 * KeySize
                 */
                put("Signature.SHA1withDSA KeySize", "1024");
                put("KeyPairGenerator.DSA KeySize", "1024");
                put("AlgorithmParameterGenerator.DSA KeySize", "1024");

                /*
                 * Implementation type: software or hardware
                 */
                put("Signature.SHA1withDSA ImplementedIn", "Software");
                put("KeyPairGenerator.DSA ImplementedIn", "Software");
                put("MessageDigest.MD5 ImplementedIn", "Software");
                put("MessageDigest.SHA ImplementedIn", "Software");
                put("AlgorithmParameterGenerator.DSA ImplementedIn",
                    "Software");
                put("AlgorithmParameters.DSA ImplementedIn", "Software");
                put("KeyFactory.DSA ImplementedIn", "Software");
                put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
                put("CertificateFactory.X509 ImplementedIn", "Software");
                put("KeyStore.JKS ImplementedIn", "Software");

                return null;
            }
        });
    }
}

Приложение B: Мастер класс Провайдера SunJCE

Ниже сокращенная версия SunJCE.java файл, который содержит названный class SunJCE это - основной class для провайдера под названием SunJCE.

Как со всеми мастер классами, этот class является подклассом Provider. Это определяет имена class и расположения пакета всех реализаций криптографической службы, предоставленных провайдером SunJCE. Эта информация используется getInstance методы классов механизма, чтобы искать различные алгоритмы и другие службы, когда их требуют.

Этот код предоставляется как пример ведущего устройства провайдера class.

/*
 * @(#)SunJCE.java      1.73 05/12/13
 *
 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package com.sun.crypto.provider;

import java.security.*;
import java.security.cert.*;
import java.net.URL;
import java.io.ByteArrayInputStream;

/**
 * The "SunJCE" Cryptographic Service Provider.
 *
 * @author Jan Luehe
 * @author Sharon Liu
 *
 * @version 1.73, 12/13/05
 */

/**
 * Defines the "SunJCE" provider.
 *
 * Supported algorithms and their names:
 *
 * ...edited for space...
 *
 */

public final class SunJCE extends Provider {

    private static final String info = "SunJCE Provider " +
    "(implements RSA, DES, Triple DES, AES, Blowfish, ARCFOUR, RC2, PBE, "
    + "Diffie-Hellman, HMAC)";

    private static final String OID_PKCS5_MD5_DES = "1.2.840.113549.1.5.3";
    private static final String OID_PKCS3 = "1.2.840.113549.1.3.1";

    public SunJCE() {
        /* We are the "SunJCE" provider */
        super("SunJCE", 1.6d, info);

        final String BLOCK_MODES = "ECB|CBC|PCBC|CTR|CTS|CFB|OFB" +
            "|CFB8|CFB16|CFB24|CFB32|CFB40|CFB48|CFB56|CFB64" +
            "|OFB8|OFB16|OFB24|OFB32|OFB40|OFB48|OFB56|OFB64";
        final String BLOCK_MODES128 = BLOCK_MODES +
            "|CFB72|CFB80|CFB88|CFB96|CFB104|CFB112|CFB120|CFB128" +
            "|OFB72|OFB80|OFB88|OFB96|OFB104|OFB112|OFB120|OFB128";
        final String BLOCK_PADS = "NOPADDING|PKCS5PADDING|ISO10126PADDING";

        AccessController.doPrivileged(new java.security.PrivilegedAction() {
                public Object run() {

                /*
                 * Cipher engines
                 */
                put("Cipher.RSA", "com.sun.crypto.provider.RSACipher");
                put("Cipher.RSA SupportedModes", "ECB");
                put("Cipher.RSA SupportedPaddings",
                        "NOPADDING|PKCS1PADDING|OAEPWITHMD5ANDMGF1PADDING"
                        + "|OAEPWITHSHA1ANDMGF1PADDING"
                        + "|OAEPWITHSHA-1ANDMGF1PADDING"
                        + "|OAEPWITHSHA-256ANDMGF1PADDING"
                        + "|OAEPWITHSHA-384ANDMGF1PADDING"
                        + "|OAEPWITHSHA-512ANDMGF1PADDING");
                put("Cipher.RSA SupportedKeyClasses",
                        "java.security.interfaces.RSAPublicKey" +
                        "|java.security.interfaces.RSAPrivateKey");

                put("Cipher.PBEWithMD5AndDES",
                    "com.sun.crypto.provider.PBEWithMD5AndDESCipher");
                put("Alg.Alias.Cipher.OID."+OID_PKCS5_MD5_DES,
                    "PBEWithMD5AndDES");
                put("Alg.Alias.Cipher."+OID_PKCS5_MD5_DES,
                    "PBEWithMD5AndDES");

                put("Cipher.AES", "com.sun.crypto.provider.AESCipher");
                put("Alg.Alias.Cipher.Rijndael", "AES");
                put("Cipher.AES SupportedModes", BLOCK_MODES128);
                put("Cipher.AES SupportedPaddings", BLOCK_PADS);
                put("Cipher.AES SupportedKeyFormats", "RAW");

                put("Cipher.AESWrap", "com.sun.crypto.provider.AESWrapCipher");
                put("Cipher.AESWrap SupportedModes", "ECB");
                put("Cipher.AESWrap SupportedPaddings", "NOPADDING");
                put("Cipher.AESWrap SupportedKeyFormats", "RAW");

                put("Cipher.ARCFOUR",
                    "com.sun.crypto.provider.ARCFOURCipher");
                put("Alg.Alias.Cipher.RC4", "ARCFOUR");
                put("Cipher.ARCFOUR SupportedModes", "ECB");
                put("Cipher.ARCFOUR SupportedPaddings", "NOPADDING");
                put("Cipher.ARCFOUR SupportedKeyFormats", "RAW");

                /*
                 *  Key(pair) Generator engines
                 */
                put("KeyGenerator.AES",
                    "com.sun.crypto.provider.AESKeyGenerator");
                put("Alg.Alias.KeyGenerator.Rijndael", "AES");

                put("KeyGenerator.ARCFOUR",
                    "com.sun.crypto.provider.KeyGeneratorCore$" +
                    "ARCFOURKeyGenerator");
                put("Alg.Alias.KeyGenerator.RC4", "ARCFOUR");

                put("KeyGenerator.HmacMD5",
                    "com.sun.crypto.provider.HmacMD5KeyGenerator");

                put("KeyGenerator.HmacSHA256",
                    "com.sun.crypto.provider.KeyGeneratorCore$HmacSHA256KG");

                put("KeyPairGenerator.DiffieHellman",
                    "com.sun.crypto.provider.DHKeyPairGenerator");
                put("Alg.Alias.KeyPairGenerator.DH", "DiffieHellman");
                put("Alg.Alias.KeyPairGenerator.OID."+OID_PKCS3,
                    "DiffieHellman");
                put("Alg.Alias.KeyPairGenerator."+OID_PKCS3,
                    "DiffieHellman");

                /*
                 * Algorithm parameter generation engines
                 */
                put("AlgorithmParameterGenerator.DiffieHellman",
                    "com.sun.crypto.provider.DHParameterGenerator");
                put("Alg.Alias.AlgorithmParameterGenerator.DH",
                    "DiffieHellman");
                put("Alg.Alias.AlgorithmParameterGenerator.OID."+OID_PKCS3,
                    "DiffieHellman");
                put("Alg.Alias.AlgorithmParameterGenerator."+OID_PKCS3,
                    "DiffieHellman");

                /*
                 * Key Agreement engines
                 */
                put("KeyAgreement.DiffieHellman",
                    "com.sun.crypto.provider.DHKeyAgreement");
                put("Alg.Alias.KeyAgreement.DH", "DiffieHellman");
                put("Alg.Alias.KeyAgreement.OID."+OID_PKCS3, "DiffieHellman");
                put("Alg.Alias.KeyAgreement."+OID_PKCS3, "DiffieHellman");

                put("KeyAgreement.DiffieHellman SupportedKeyClasses",
                    "javax.crypto.interfaces.DHPublicKey" +
                    "|javax.crypto.interfaces.DHPrivateKey");

                /*
                 * Algorithm Parameter engines
                 */
                put("AlgorithmParameters.DiffieHellman",
                    "com.sun.crypto.provider.DHParameters");
                put("Alg.Alias.AlgorithmParameters.DH", "DiffieHellman");
                put("Alg.Alias.AlgorithmParameters.OID."+OID_PKCS3,
                    "DiffieHellman");
                put("Alg.Alias.AlgorithmParameters."+OID_PKCS3,
                    "DiffieHellman");

                put("AlgorithmParameters.PBEWithMD5AndDES",
                    "com.sun.crypto.provider.PBEParameters");
                put("Alg.Alias.AlgorithmParameters.OID."+OID_PKCS5_MD5_DES,
                    "PBEWithMD5AndDES");
                put("Alg.Alias.AlgorithmParameters."+OID_PKCS5_MD5_DES,
                    "PBEWithMD5AndDES");

                put("AlgorithmParameters.OAEP",
                    "com.sun.crypto.provider.OAEPParameters");

                /*
                 * Key factories
                 */
                put("KeyFactory.DiffieHellman",
                    "com.sun.crypto.provider.DHKeyFactory");
                put("Alg.Alias.KeyFactory.DH", "DiffieHellman");
                put("Alg.Alias.KeyFactory.OID."+OID_PKCS3,
                    "DiffieHellman");
                put("Alg.Alias.KeyFactory."+OID_PKCS3, "DiffieHellman");

                /*
                 * Secret-key factories
                 */
                put("SecretKeyFactory.PBEWithMD5AndDES",
                    "com.sun.crypto.provider.PBEKeyFactory$PBEWithMD5AndDES"
                    );
                put("Alg.Alias.SecretKeyFactory.OID."+OID_PKCS5_MD5_DES,
                    "PBEWithMD5AndDES");
                put("Alg.Alias.SecretKeyFactory."+OID_PKCS5_MD5_DES,
                    "PBEWithMD5AndDES");

                /*
                 * MAC
                 */
                put("Mac.HmacMD5", "com.sun.crypto.provider.HmacMD5");
                put("Mac.HmacSHA256",
                    "com.sun.crypto.provider.HmacCore$HmacSHA256");

                put("Mac.HmacMD5 SupportedKeyFormats", "RAW");
                put("Mac.HmacSHA256 SupportedKeyFormats", "RAW");

                /*
                 * KeyStore
                 */
                put("KeyStore.JCEKS", "com.sun.crypto.provider.JceKeyStore");

                return null;
            }
        });
    }
}
 

Приложение C: java.security.properties Файл

Ниже часть java.security файл, который показывает список значения по умолчанию установленных провайдеров. Это появляется в каждой установке JRE. Файл также содержит другие записи, но для краткости, мы показываем только часть файла здесь. См. полный файл в:

<java-home>/lib/security/java.security     [Solaris]
<java-home>\lib\security\java.security     [Win32]

Здесь <java-home> ссылается на каталог, где JRE был установлен.

См. Шаг 5 для примера добавляющей информации о Вашем провайдере к этому файлу.

#
# This is the "master security properties file".
#
# In this file, various security properties are set for use by
# java.security classes. This is where users can statically register
# Cryptography Package Providers ("providers" for short). The term
# "provider" refers to a package or set of packages that supply a
# concrete implementation of a subset of the cryptography aspects of
# the Java Security API. A provider may, for example, implement one or
# more digital signature algorithms or message digest algorithms.
#
# Each provider must implement a subclass of the Provider class.
# To register a provider in this master security properties file,
# specify the Provider subclass name and priority in the format
#
#    security.provider.<n>=<className>
#
# This declares a provider, and specifies its preference
# order n. The preference order is the order in which providers are
# searched for requested algorithms (when no specific provider is
# requested). The order is 1-based; 1 is the most preferred, followed
# by 2, and so on.
#
# <className> must specify the subclass of the Provider class whose
# constructor sets the values of various properties that are required
# for the Java Security API to look up the algorithms or other
# facilities implemented by the provider.
#
# There must be at least one provider specification in java.security.
# There is a default provider that comes standard with the JDK. It
# is called the "SUN" provider, and its Provider subclass
# named Sun appears in the sun.security.provider package. Thus, the
# "SUN" provider is registered via the following:
#
#    security.provider.1=sun.security.provider.Sun
#
# (The number 1 is used for the default provider.)
#
# Note: Providers can be dynamically registered instead by calls to
# either the addProvider or insertProviderAt method in the Security
# class.

#
# List of providers and their preference orders (see above):
#

security.provider.1=sun.security.pkcs11.SunPKCS11 \
    ${java.home}/lib/security/sunpkcs11-solaris.cfg
security.provider.2=sun.security.provider.Sun
security.provider.3=sun.security.rsa.SunRsaSign
security.provider.4=com.sun.net.ssl.internal.ssl.Provider
security.provider.5=com.sun.crypto.provider.SunJCE
security.provider.6=sun.security.jgss.SunProvider
security.provider.7=com.sun.security.sasl.Provider
security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.9=sun.security.smartcardio.SunPCSC

# Rest of file deleted


Oracle и/или его филиалы Авторское право © 1993, 2012, Oracle и/или его филиалы. Все права защищены.
Свяжитесь с Нами