Spec-Zone .ru
спецификации, руководства, описания, API
|
Provider.Service
Классjava.security
Файл свойствПлатформа Java определяет ряд API, охватывающих главные области безопасности, включая криптографию, инфраструктуру управления открытыми ключами, аутентификацию, безопасную передачу, и управление доступом. Эти API позволяют разработчикам легко интегрировать безопасность в свой код программы. Они были разработаны вокруг следующих принципов:
Независимость реализации
Приложения не должны реализовать безопасность самостоятельно. Скорее они могут запросить службы безопасности с платформы Java. Службы безопасности реализуются в провайдерах (см. ниже), которые включаются в платформу Java через стандартный интерфейс. Приложение может положиться на многократных независимых провайдеров для функциональности безопасности.
Функциональная совместимость реализации
Провайдеры являются взаимодействующими через приложения. Определенно, приложение не связывается с определенным провайдером, и провайдер не связывается с определенным приложением.
Расширяемость алгоритма
Платформа Java включает много встроенных провайдеров, которые реализуют основной набор служб безопасности, которые широко используются сегодня. Однако, некоторые приложения могут положиться на появляющиеся стандарты, еще реализованные, или на собственных службах. Платформа Java поддерживает установку пользовательских провайдеров, которые реализуют такие службы.
Провайдер криптографических служб (провайдер) обращается к пакету (или ряд пакетов), которые предоставляют конкретную реализацию подмножества аспектов криптографии API Безопасности JDK.
java.security.Provider
class инкапсулирует понятие поставщика систем обеспечения безопасности в платформе Java. Это определяет имя провайдера и перечисляет службы безопасности, которые это реализует. Многократные провайдеры могут быть сконфигурированы одновременно, и перечисляются в порядке предпочтения. Когда службу безопасности требуют, самый высокий приоритетный провайдер, который реализует ту службу, выбирается.
Рисунки 1 и 2 иллюстрируют эти опции для того, чтобы запросить реализацию обзора сообщения MD5. Оба данных показывают трех провайдеров что алгоритмы обзора сообщения реализации. Провайдеры упорядочиваются предпочтением слева направо (1-3). В рисунке 1 приложение запрашивает реализацию алгоритма MD5, не определяя имя провайдера. Провайдеры ищутся в привилегированном порядке и реализации от первого провайдера, предоставляющего, что определенный алгоритм, ProviderB, возвращается. В рисунке 2 приложение запрашивает реализацию алгоритма MD5 от определенного провайдера, ProviderC. На сей раз реализация от того провайдера возвращается, даже при том, что провайдер с более высоким привилегированным порядком, ProviderB, также предоставляет реализацию MD5.
Рисунок 1 (уехал): поиск Провайдера. Рисунок 2 (право): Определенного провайдера требуют
У каждой установки есть один или более установленных пакетов провайдера. Клиенты могут сконфигурировать свои времена выполнения с различными провайдерами, и определить привилегированный порядок на каждого из них. Привилегированный порядок является порядком, в котором провайдеры ищутся требуемые алгоритмы, когда никакого определенного провайдера не требуют.
Версия Sun среды выполнения Java прибывает стандарт с провайдером значения по умолчанию, названным "SUN". Другие среды выполнения Java, возможно, не обязательно предоставляют провайдера "SUN".
Программисты, которые только должны использовать API Безопасности Java, чтобы получить доступ к существующим алгоритмам криптографии и другим службам, не должны считать этот документ.
Этот документ предназначается для опытных программистов, желающих создать их собственные пакеты провайдера, предоставляющие реализации криптографической службы. Это документирует то, что Вы должны сделать, чтобы интегрировать Вашего провайдера в Java так, чтобы Ваши алгоритмы и другие службы могли быть найдены, когда клиенты API Безопасности Java запрашивают их.
Этот документ предполагает, что Вы уже считали Справочник Архитектуры Криптографии Java.
Это документирует пакеты, которые содержат различные классы и интерфейсы в API Безопасности.
java.security
java.security.spec
java.security.interfaces
javax.crypto
javax.crypto.spec
javax.crypto.interfaces
java.security
, javax.crypto
, javax.crypto.spec
, и javax.crypto.interfaces
.Всюду по этому документу срокам JCA отдельно обращается к платформе JCA. Всякий раз, когда этот документ отмечает определенного провайдера JCA, он будет упомянут явно именем провайдера.
Механизм class определяет криптографическую службу абстрактным способом (без конкретной реализации).
Криптографическая служба всегда связывается с определенным алгоритмом или типом. Это или обеспечивает криптографические операции (как те для цифровых подписей или обзоров сообщения, шифров или протоколов согласования ключей); генерирует или предоставляет криптографический материал (ключи или параметры) требуемый для криптографических операций; или генерирует объекты данных (keystores или сертификаты), которые инкапсулируют криптографические ключи (который может использоваться в криптографической работе) безопасным способом.
Например, вот четыре класса механизма:
Signature
class обеспечивает доступ к функциональности алгоритма цифровой подписи.KeyFactory
class предоставляет закрытый ключ DSA или открытый ключ (от его кодирования или прозрачной спецификации) в формате, применимом initSign или initVerify методами, соответственно, объекта Подписи DSA.Cipher
class обеспечивает доступ к функциональности алгоритма шифрования (такого как DES)KeyAgreement
class обеспечивает доступ к функциональности протокола согласования ключей (такого как Diffie-Hellman)Архитектура Криптографии Java охватывает классы, включающие Пакет защиты, которые касаются криптографии, включая классы механизма. Пользователи API запрашивают и используют экземпляры классов механизма, чтобы выполнить соответствующие операции. JDK определяет следующие классы механизма:
MessageDigest
- используемый, чтобы вычислить обзор сообщения (хеш) указанных данных.Signature
- используемый, чтобы подписать данные и проверить цифровые подписи.KeyPairGenerator
- используемый, чтобы генерировать пару открытых и закрытых ключей, подходящих для указанного алгоритма.KeyFactory
- используемый, чтобы преобразовать непрозрачные криптографические ключи типа Key
в ключевые спецификации (прозрачные представления базового ключевого материала), и наоборот.KeyStore
- используемый, чтобы создать и управлять keystore. keystore является базой данных ключей. У закрытых ключей в keystore есть цепочка сертификата, связанная с ними, который аутентифицирует соответствующий открытый ключ. keystore также содержит сертификаты от доверяемых объектов.CertificateFactory
- используемый, чтобы создать сертификаты с открытым ключом и Списки аннулированных сертификатов (CRL).AlgorithmParameters
- используемый, чтобы управлять параметрами для определенного алгоритма, включая кодирование параметра и декодирование.AlgorithmParameterGenerator
- используемый, чтобы генерировать ряд параметров, подходящих для указанного алгоритма.SecureRandom
- используемый, чтобы генерировать случайные или псевдослучайные числа.Cipher
: используемый, чтобы зашифровать или дешифровать некоторые указанные данные.KeyAgreement
: используемый, чтобы выполнить согласование ключей (ключевой обмен) протокол между 2 или больше сторонами.KeyGenerator
: используемый, чтобы генерировать секретный (симметричный) ключ, подходящий для указанного алгоритма.Mac
: используемый, чтобы вычислить код аутентификации сообщений некоторых указанных данных.SecretKeyFactory
: используемый, чтобы преобразовать непрозрачные криптографические ключи типа SecretKey
в ключевые спецификации (прозрачные представления базового ключевого материала), и наоборот.ExemptionMechanism
: используемый, чтобы обеспечить функциональность механизма освобождения, такого как ключевое восстановление, ключевое ослабление, ключевое условное депонирование, или любой другой (пользовательский) механизм освобождения. Приложениям или апплетам, которые используют механизм освобождения, можно предоставить более сильные возможности шифрования чем те, которые не делают. Однако, пожалуйста, отметьте, что криптографические ограничения больше не требуются для большинства стран, и таким образом механизмы освобождения могут только быть полезными в тех немногих странах, правительства которых передают под мандат ограничения.Отметьте: генератор создает объекты с совершенно новым содержанием, тогда как фабрика создает объекты из существующего материала (например, кодирование).
Механизм 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:
Первая вещь, которую Вы должны сделать, состоит в том, чтобы записать код, который обеспечивает специфичные для алгоритма реализации криптографических служб, которые Вы хотите поддерживать.
Отметьте, что Ваш провайдер может предоставить реализации криптографических служб, уже доступных в один или больше компонентов безопасности JDK.
Для криптографических служб, не определенных в JCA (Например; подписи и обзоры сообщения), пожалуйста, сошлитесь на Справочник Архитектуры Криптографии Java.
Для каждой криптографической службы Вы хотите реализовать, создать подкласс соответствующего SPI class. JCA определяет следующие классы механизма:
SignatureSpi
MessageDigestSpi
KeyPairGeneratorSpi
SecureRandomSpi
AlgorithmParameterGeneratorSpi
AlgorithmParametersSpi
KeyFactorySpi
CertificateFactorySpi
KeyStoreSpi
CipherSpi
KeyAgreementSpi
KeyGeneratorSpi
MacSpi
SecretKeyFactorySpi
ExemptionMechanismSpi
(См. Классы Механизма и Соответствующие Классы SPI в этом документе для информации о JCA и другие криптографические классы.)
В Вашем подклассе Вы нуждаетесь к:
engine
. См. Дальнейшие Детали Реализации и Требования для дополнительной информации.Class
объект, связанный с Вашим подклассом, и, создает экземпляр Вашего подкласса, вызывая newInstance
метод на этом Class
объект. newInstance
требует, чтобы у Вашего подкласса был общедоступный конструктор без любых параметров.Инстанцируя реализации провайдера (class) a Cipher, KeyAgreement, KeyGenerator, MAC
или SecretKey
фабрика, платформа определит кодовую базу провайдера (файл JAR) и проверит его подпись. Таким образом JCA аутентифицирует провайдера и гарантирует, что только провайдеры, подписанные доверяемым объектом, могут быть включены в JCA. Таким образом одно требование для провайдеров шифрования - то, что они должны быть подписаны, как описано в более поздних шагах.
Кроме того, каждый провайдер должен выполнить проверку самоцелостности, чтобы гарантировать, что файлом JAR, содержащим его код, не управляли в попытке вызвать методы провайдера непосредственно, а не через JCA. Для дополнительной информации см., Как Провайдер Может Сделать Проверку Самоцелостности.
Для классов провайдера, чтобы стать неприменимый если инстанцировано приложением непосредственно, обходя JCA, провайдеры должны реализовать следующее:
Для провайдеров, которые могут быть экспортированы вне США, CipherSpi
реализации должны включать реализацию engineGetKeySize
метод, который, данный a Key
, возвращает размер ключа. Если есть ограничения на доступную криптографическую силу, определенную в файлах политики юрисдикции, каждом Cipher
вызовы метода инициализации engineGetKeySize
и затем сравнивает результат с максимальным допустимым размером ключа для определенного расположения и обстоятельств апплета или запущенного приложения. Если размер ключа является слишком большим, метод инициализации выдает исключение.
Дополнительные дополнительные функции, которые могут реализовать провайдеры,
engineWrap
и engineUnwrap
методы CipherSpi
. Обертывание ключа включает безопасной передаче ключа от одного места до другого. Информация об обертывании и разворачивании ключей предоставляется в Обертывании и Разворачивании Ключевого раздела Справочника Архитектуры Криптографии Java.Выберите имя для своего провайдера. Это - имя, которое будет использоваться клиентскими приложениями, чтобы обратиться к Вашему провайдеру.
Третий шаг должен создать подкласс java.security.Provider
class.
Ваш подкласс должен быть a final
class, и его конструктор должны
super
, определение имени провайдера (см. Шаг 2), номера версии, и строки информации о провайдере и алгоритмах он поддерживает. Например: super("CryptoX", 1.0, "CryptoX provider v1.0, implementing " + "RSA encryption and key pair generation, and DES encryption.");
Список ниже показывает различные типы служб JCA, где фактическое имя алгоритма является substitued для algName:
Signature.algName
MessageDigest.algName
KeyPairGenerator.algName
SecureRandom.algName
AlgorithmParameterGenerator.algName
AlgorithmParameters.algName
KeyFactory.algName
CertificateFactory.algName
KeyStore.algName
Cipher.algName
KeyAgreement.algName
KeyGenerator.algName
Mac.algName
SecretKeyFactory.algName
ExemptionMechanism.algName
Во всех них кроме ExemptionMechanism
и Cipher
, algName, certType
, или storeType
"стандартное" имя алгоритма, типа сертификата, или типа keystore. См. Приложение A Справочника Архитектуры Криптографии Java для стандартных имен, которые должны использоваться.)
В случае ExemptionMechanism
, algName обращается к имени механизма освобождения, который может быть одним из следующего: KeyRecovery
, KeyEscrow
, или KeyWeakening
. Случай не имеет значения.
В случае Cipher
, algName может фактически представить преобразование, и может быть составлен из имени алгоритма, определенного режима, и дополнительной схемы. См. Приложение A Справочника Архитектуры Криптографии Java для деталей.
Значение каждого свойства должно быть полностью определенным именем class, реализовывая указанный алгоритм, тип сертификата, или тип keystore. Таким образом, это должно быть имя пакета, сопровождаемое именем class, где эти два разделяются периодом.
Как пример, провайдер значения по умолчанию под названием SUN реализует Алгоритм цифровой подписи (чье стандартное имя SHA1withDSA
) в названном class DSA
в sun.security.provider
пакет. Его подкласс Provider
(который является Sun class в sun.security.provider package
) наборы Signature.SHA1withDSA
свойство, чтобы иметь значение sun.security.provider.DSA
через следующее:
put("Signature.SHA1withDSA", "sun.security.provider.DSA")
Список ниже показывает больше свойств, которые могут быть определены для различных типов служб, где фактическое имя алгоритма является substitued для algName, типом сертификата для certType, keystore тип для storeType, и название атрибута для attrName:
Signature.algName [one or more spaces] attrName
MessageDigest.algName [one or more spaces] attrName
KeyPairGenerator.algName [one or more spaces] attrName
SecureRandom.algName [one or more spaces] attrName
KeyFactory.algName [one or more spaces] attrName
CertificateFactory.certType [one or more spaces] attrName
KeyStore.storeType [one or more spaces] attrName
AlgorithmParameterGenerator.algName [one or more spaces] attrName
AlgorithmParameters.algName [one or more spaces] attrName
Cipher.algName [one or more spaces] attrName
KeyAgreement.algName [one or more spaces] attrName
KeyGenerator.algName [one or more spaces] attrName
Mac.algName [one or more spaces] attrName
SecretKeyFactory.algName [one or more spaces] attrName
ExemptionMechanism.algName [one or more spaces] attrName
В каждом из них, 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.
Как упомянуто выше, в случае 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:
Cipher.DES/ECB/PKCS5Padding
Cipher.DES/CBC/PKCS5Padding
Cipher.DES/CFB/PKCS5Padding
Cipher.DES/OFB/PKCS5Padding
Другой провайдер может реализовать class для каждого из вышеупомянутых режимов (то есть, один class для ECB, один для CBC, один для CFB, и один для OFB), один class для PKCS5Padding, и универсальный DES class, который разделяет на подклассы от CipherSpi
. У того провайдера был бы следующий Cipher
свойства в его основном class:
Cipher.DES
Cipher.DES SupportedModes
Example: "ECB|CBC|CFB|OFB"
Cipher.DES SupportedPaddings
Example: "NOPADDING|PKCS5Padding"
getInstance
метод фабрики Cipher
class механизма следует за этими правилами, чтобы инстанцировать реализации провайдера CipherSpi
для преобразования формы "алгоритм":
CipherSpi
для указанного "алгоритма".NoSuchAlgorithmException
исключение. getInstance
метод фабрики Cipher
class механизма следует за этими правилами, чтобы инстанцировать реализации провайдера CipherSpi
для преобразования формы "алгоритм/режим/дополнение":
CipherSpi
для указанного преобразования "алгоритма/режима/дополнения".CipherSpi
для подпреобразования "алгоритм/режим".engineSetPadding(padding)
на новом экземпляре.CipherSpi
для подпреобразования "алгоритм//дополняющий" (отмечают двойные наклонные черты).engineSetMode(mode)
на новом экземпляре.CipherSpi
для подпреобразования "алгоритм".engineSetMode(mode)
и engineSetPadding(padding)
на новом экземпляре.NoSuchAlgorithmException
исключение.После того, как Вы создали свой код реализации (Шаг 1), учитывая Вашего провайдера имя (Шаг 2), и создали основной class (Шаг 3), используйте компилятор Java, чтобы скомпилировать Ваши файлы.
Поместите свой код провайдера в файл JAR в подготовку к подписанию этого в следующем шаге. Для получения дополнительной информации по инструменту фляги см. флягу (для Соляриса) (для Microsoft Windows).
jar cvf <JAR file name> <list of classes, separated by spaces>
Эта команда создает файл JAR с указанным именем, содержащим указанные классы.
Если Ваш провайдер предоставляет алгоритмы шифрования через Cipher KeyAgreement, KeyGenerator, Mac,
или SecretKeyFactory
классы, Вы должны будете подписать свой файл JAR так, чтобы JCA мог аутентифицировать код во времени выполнения. Для получения дополнительной информации см. Шаг 1a. Если Вы НЕ обеспечиваете реализацию этого типа, можно пропустить этот шаг.
Следующий шаг должен запросить сертификат для подписывания кода так, чтобы можно было использовать его, чтобы подписать Вашего провайдера до тестирования. Сертификат будет хорош и для тестирования и для производства. Это будет допустимо в течение 5 лет.
Ниже шаги, которые следует использовать, чтобы получить сертификат для подписывания кода. Для получения дополнительной информации по keytool инструменту см. keytool (для Соляриса) (для Microsoft Windows).
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, введите имя файла (с его путем, в случае необходимости). Это заставит команду в пакетном файле выполняться.
keytool -certreq -alias <alias> \ -file <csr file name> \ -keystore <keystore file name> \ -storepass <keystore password>Здесь,
<alias>
псевдоним для записи пары ключей DSA, создаваемой в предыдущем шаге. Эта команда генерирует Запрос Подписания Сертификата (CSR), используя PKCS#10 формат. Это хранит CSR в файле, имя которого определяется в <csr file name>
.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).
Подпишите файл 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>
Текст "фляга, проверенная", будет выведен на экран, если проверка была успешна.
Следующие шаги описывают, как установить и сконфигурировать Вашего нового провайдера так, чтобы это было доступно через JCA.
Чтобы подготовиться к тестированию Вашего провайдера, следует установить его тем же самым способом, как будет сделан клиентами, желающими использовать это. Установка позволяет Безопасности 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.
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"; };
Всякий раз, когда провайдеры не являются установленными расширениями, полномочия нужно предоставить для того, когда апплеты или приложения выполняются, в то время как менеджер безопасности устанавливается. обычно есть менеджер безопасности, установленный всякий раз, когда апплет работает, и менеджер безопасности может быть установлен для приложения или через код в приложении непосредственно или через параметр командной строки. Полномочия не должны предоставить установленным расширениям, так как системный файл политики значения по умолчанию предоставляет все полномочия установленным расширениям.
Всякий раз, когда клиент не устанавливает Вашего провайдера как установленное расширение, Вашему провайдеру, возможно, понадобятся следующие полномочия, предоставленные ему в клиентской среде:
java.lang.RuntimePermission
получить домены защиты class. Провайдер, возможно, должен получить свой домен собственной защиты в процессе выполнения проверки самоцелостности.java.security.SecurityPermission
установить свойства провайдера.Гарантировать Вашего провайдера работает, когда менеджер безопасности устанавливается, и провайдер не является установленным расширением, Вы должны протестировать такую установку и среду выполнения. Кроме того, до тестирования Вы должны предоставить соответствующие полномочия своему провайдеру и любым другим провайдерам, которых это использует. Например, демонстрационное предоставление оператора полномочия к провайдеру, имя которого является "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"; };
Запишите и скомпилируйте одну или более тестовых программ, которые тестируют объединение Вашего провайдера в 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 для полной информации о создании и тестировании такого приложения.
Выполните свою тестовую программу (ы). Отладьте свой код и продолжайте тестировать как необходимый. Если API Безопасности Java, может казаться, не находит один из Ваших алгоритмов, не рассматривает шаги выше и не гарантирует, что они все завершаются.
Убедитесь, что включали тестирование своих программ, используя различные опции инсталляции (например, делающий провайдера установленное расширение или помещающий это в путь class) и среды выполнения (с или без выполнения менеджера безопасности). Опции инсталляции обсуждаются в Шаге 7.1. В частности Вы должны гарантировать свои работы провайдера, когда менеджер безопасности устанавливается, и провайдер не является установленным расширением - и таким образом провайдеру нужно было предоставить полномочия этому; поэтому, Вы должны протестировать такую установку и среду выполнения после предоставления необходимых полномочий к Вашему провайдеру и к любым другим провайдерам, которых это использует, как описано в Шаге 7.2.
Если Вы находите во время тестирования, что Ваш код нуждается в модификации, произведите изменения, перекомпилируйте (Шаг 4), поместите обновленный код провайдера в файл JAR (Шаг 6), подпишите файл JAR в случае необходимости (Шаг 6.2), переустановите провайдера (Шаг 7.1), если нужно фиксируйте или добавьте к полномочиям (Шаг 7.2), и затем повторно протестируйте Ваши программы. Повторите эти шаги как необходимый.
Все американские поставщики, провайдеры которых могут быть экспортированы вне США, должны примениться к Бюро Отрасли и Безопасности в американском Министерстве торговли для одобрения экспорта. Пожалуйста, консультируйтесь со своим адвокатом экспорта для получения дополнительной информации.
Отметьте: Если Ваш провайдер вызывает Cipher.getInstance()
и возвращенный Cipher
возразите должен выполнить криптографию strong независимо от того, что криптографическая сила позволяется загруженными файлами политики юрисдикции пользователя, следует включать копию cryptoPerms
файл политики разрешения, который Вы намереваетесь связать в файле JAR для Вашего провайдера и который определяет соответствующее разрешение для необходимой криптографической силы. Потребность этого файла точно так же как требование, чтобы апплеты и приложения, "освобожденные" от криптографических ограничений, включали a cryptoPerms
файл политики разрешения в их файле JAR. Для получения дополнительной информации по созданию и включению такого файла, см., Как Подать Заявки, "Освобожденные" от Криптографических Ограничений в Справочнике Архитектуры Криптографии Java.
Вот два URL, которые могут быть полезными:
Следующий шаг должен записать документацию для Ваших клиентов. В минимуме Вы должны определить:
Кроме того, Ваша документация должна определить что-либо еще интереса для клиентов, таких как любые параметры алгоритма значения по умолчанию.
Для каждого сообщения Обзор и алгоритм 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 }
где:
mac
объект MAC, который что они получили, когда они запрашивали один через звонок Mac.getInstance
,i1
, i2
и i3
входные байтовые массивы, иi1
i1 and i2
i1, i2, and i3
Для алгоритма генератора пары ключей, в случае, если клиент явно не инициализирует генератор пары ключей (через звонок 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 (и его инкапсулировавший объект реализации SecureRandomSpi) десериализовываются: Если последующие звонки nextBytes
метод (который вызывает engineNextBytes
метод инкапсулировавшего объекта SecureRandomSpi) восстановленного объектного урожая, те же самые (случайные) байты как исходный объект были бы, затем позвольте пользователям знать, что, если это поведение является нежелательным, они должны отобрать восстановленный случайный объект, вызывая setSeed
метод.
Провайдер должен задокументировать, какие типы сертификатов (и их номера версий, если релевантный), может быть создан фабрикой.
Провайдер должен задокументировать любую релевантную информацию относительно keystore реализации, такой как ее базовый формат данных.
После записи, конфигурирования, тестирование, установка и документирование Вашего программного обеспечения провайдера, делает документацию доступной для Ваших клиентов.
Каждый провайдер должен сделать проверку самоцелостности, чтобы гарантировать, что в файл JAR, содержащий его код, не вмешались, например в попытке вызвать методы провайдера непосредственно, а не через JCA. Провайдеры, которые обеспечивают реализации для служб шифрования (Cipher, KeyAgreement, KeyGenerator, MAC
или SecretKey
фабрика), должен быть в цифровой форме подписан и должен быть подписан с сертификатом, выпущенным "доверяемыми" Центрами сертификации. В настоящий момент следующие два Центра сертификации считают "доверяемыми":
Пожалуйста, обратитесь к Шагу 6.2 для получения дальнейшей информации на том, как получить сертификат для подписывания кода от CA Подписывания кода Sun Microsystems JCA и сертификата о том CA.
После получения сертификата подписания от вышеупомянутого Центра сертификации пакеты провайдера должны встроить в пределах себя байты для его собственного сертификата подписания, например в массиве как bytesOfProviderCert
массив, упомянутый в Идентификации Каждого из Подписывающих лиц и Определения, Если Вы - раздел, Которому доверяют, ниже. Во времени выполнения встроенный сертификат будет использоваться в определении, подлинен ли код провайдера.
Основной подход, который провайдер может использовать, чтобы проверить его собственную целостность:
Каждый из этих шагов описывается в следующих разделах:
Отметьте: пример кода 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
. . . }
URL для файла JAR провайдера может быть получен, определяя провайдера CodeSource
и затем вызов getLocation
метод на CodeSource
.
URL providerURL = (URL) AccessController.doPrivileged( new PrivilegedAction) { public Object run() { CodeSource cs = MyJCE.class.getProtectionDomain().getCodeSource(); return cs.getLocation(); } });
Как только у Вас есть 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();
Как только Вы определили URL для своего файла JAR провайдера, и Вы создали a JarFile
обращаясь к файлу JAR, как показано в шагах выше, можно тогда проверить файл.
Основной подход:
Пример кода для каждого из этих шагов представляется и описывается в следующих разделах:
Наш подход должен определить 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 вмешались, если он не подписывается:
// 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):
Установка цикла является следующим:
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.java
, демонстрационный провайдер, у которого есть метод selfIntegrityChecking
который выполняет проверку самоцелостности. Это сначала определяет URL своего собственного файла JAR провайдера и затем проверяет, что файл JAR провайдера подписывается со встроенным сертификатом для подписывания кода.
Отметьте: метод selfIntegrityChecking
должен быть вызван всеми конструкторами его криптографических классов механизма, чтобы гарантировать, что его целостность не ставится под угрозу.
Провайдер MyJCE
выполняет самоцелостность, регистрируясь в следующих шагах:
MyJCE.class
.JarVerifier
объект с провайдером URL в Шаге 1.X509Certificate
объект от встроенного байтового массива bytesOfProviderCert
.JarVerifier.verify
метод, чтобы проверить все записи в файле JAR провайдера подписывается и подписывается с тем же самым сертификатом, который инстанцируют в Шаге 3.Отметьте: class JarVerifier
получит файл JAR от данного URL, удостоверьтесь, что файл JAR подписывается, у всех записей есть действительные подписи, и это, записи подписываются с указанным X509Certificate
.
Исключение безопасности выдается JarVerifier.verify
в нескольких случаях:
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 обычно должен использовать алгоритм обзора сообщения, чтобы преобразовать пароль в ключ.
Если Вы реализуете один тип алгоритма, который требует другого, можно сделать одно из следующего:
MessageDigest.getInstance("MD5", "SUN")
MessageDigest.getInstance("MD5")Это является только соответствующим, если Вы уверены, что будет по крайней мере одна реализация требуемого алгоритма (в этом случае, MD5) установлена на каждой платформе Java, где Ваш провайдер будет использоваться.
Вот некоторые общие типы взаимозависимостей алгоритма:
Алгоритм подписи часто требует использования алгоритма обзора сообщения. Например, алгоритм подписи SHA1withDSA требует SHA 1 алгоритм обзора сообщения.
Алгоритм подписи часто требует использования (псевдо-) алгоритм генерации случайных чисел. Например, такой алгоритм требуется, чтобы генерировать подпись DSA.
Алгоритм генерации пары ключей часто требует использования алгоритма обзора сообщения. Например, ключи DSA сгенерированы, используя SHA 1 алгоритм обзора сообщения.
Генератор параметра алгоритма часто требует использования алгоритма обзора сообщения. Например, параметры DSA сгенерированы, используя SHA 1 алгоритм обзора сообщения.
keystore реализация будет часто использовать алгоритм обзора сообщения, чтобы вычислить хэширование по ключу (где key
пользовательский указанный пароль) проверить целостность keystore и удостовериться, что в keystore не вмешались.
Алгоритм генерации пары ключей иногда должен генерировать новый набор параметров алгоритма. Это может или генерировать параметры непосредственно, или использовать генератор параметра алгоритма.
Алгоритм генерации пары ключей может потребовать источника случайности, чтобы генерировать новую пару ключей и возможно новый набор параметров, связанных с ключами. Тот источник случайности представляется a SecureRandom
объект. Реализация алгоритма генерации пары ключей может генерировать основные параметры самостоятельно, или может использовать генератор параметра алгоритма, чтобы генерировать их, когда это может или, возможно, не инициализирует генератор параметра алгоритма с источником случайности.
Генератор параметра алгоритма engineGenerateParameters
метод должен возвратиться AlgorithmParameters
экземпляр.
Если Вы реализуете алгоритм подписи, Ваша реализация engineInitSign
и engineInitVerify
методы потребуют, передал - в ключах, которые допустимы для базового алгоритма (например, ключи DSA для алгоритма DSS). Можно сделать одно из следующего:
DSAPrivateKey
и DSAPublicKey
интерфейсы от пакета java.security.interfaces
), и создайте свой собственный генератор пары ключей и/или ключевые ключи возврата фабрики тех типов. Потребуйте ключей, к которым передают engineInitSign
и engineInitVerify
чтобы быть типами ключей, Вы реализовали, то есть, ключи, сгенерированные от Вашего генератора пары ключей или ключевой фабрики. Или Вы можете,engineInitSign
метод для Подписи DSS, class мог принять любые закрытые ключи, которые являются экземплярами java.security.interfaces.DSAPrivateKey
.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 }
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, который реализует
getX
метод от DSAPrivateKey
интерфейс.getParams
метод от java.security.interfaces.DSAKey
интерфейс, с тех пор DSAPrivateKey
расширяется DSAKey
. Отметьте: getParams
метод возвращает a DSAParams
объект, таким образом, у Вас должен также быть a DSAParams
реализация.getAlgorithm
, getEncoded
, и getFormat
методы от java.security.Key
интерфейс, с тех пор DSAPrivateKey
расширяется java.security.PrivateKey
, и PrivateKey
расширяется Key
. Точно так же для общедоступных ключей DSA, Вы должны предоставить class, который реализует:
getY
метод от интерфейса DSAPublicKey.getParams
метод от java.security.interfaces.DSAKey
интерфейс, с тех пор DSAPublicKey
расширяет DSAKey. Отметьте: getParams
метод возвращает a DSAParams
объект, таким образом, у Вас должен также быть a DSAParams
реализация.getAlgorithm
, getEncoded
, и getFormat
методы от java.security.Key
интерфейс, с тех пор DSAPublicKey
расширяется java.security.PublicKey
, и PublicKey
расширяется Key
.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, который реализует:
getModulus
и getPrivateExponent
методы от RSAPrivateKey
интерфейс.getAlgorithm
, getEncoded
, и getFormat
методы от java.security. Ключевой интерфейс, с тех пор RSAPrivateKey
расширяется java.security.PrivateKey
, и PrivateKey
расширяется Key
.Точно так же для закрытых ключей RSA, используя китайскую Теорему Остатка (CRT) представление, Вы должны предоставить class, который реализует:
RSAPrivateCrtKey
расширяется java.security.interfaces.RSAPrivateKey
.getPublicExponent
, getPrimeP
, getPrimeQ
, getPrimeExponentP
, getPrimeExponentQ
, и getCrtCoefficient
методы от RSAPrivateKey
интерфейс.Для общедоступных ключей RSA Вы должны предоставить class, который реализует:
getModulus
и getPublicExponent
методы от RSAPublicKey
интерфейс.getAlgorithm
, getEncoded
, и getFormat
методы от java.security. Ключевой интерфейс, с тех пор RSAPublicKey
расширяется java.security.PublicKey
, и PublicKey
расширяется Key
.JCA содержит много AlgorithmParameterSpec
реализации для наиболее часто используемого шифра и параметров алгоритма согласования ключей. Если Вы будете работать на параметрах алгоритма, которые должны быть для различного типа алгоритма, не обеспеченного JCA, то Вы должны будете предоставить свое собственное AlgorithmParameterSpec
реализация, подходящая для того типа алгоритма.
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) используемый с шифром в режиме обратной связи.
Метод | Описание |
---|---|
byte[] getIV() |
Возвращает вектор инициализации (IV). |
OAEPParameterSpec
КлассЭтот class определяет набор параметров, используемых с Дополнением OAEP, как определено в PKCS #1 стандарт.
Метод | Описание |
---|---|
String getDigestAlgorithm() |
Возвращает имя алгоритма обзора сообщения. |
String getMGFAlgorithm() |
Возвращает имя алгоритма функции генерации маски. |
AlgorithmParameterSpec getMGFParameters() |
Возвращает параметры для функции генерации маски. |
PSource getPSource() |
Возвращает источник кодирования ввода P. |
PBEParameterSpec
КлассЭтот class (который реализует AlgorithmParameterSpec
интерфейс), определяет набор параметров, используемых с основанным на пароле шифрованием (PBE) алгоритм.
Метод | Описание |
---|---|
int getIterationCount() |
Возвращает итеративное количество. |
byte[] getSalt() |
Возвращает соль. |
RC2ParameterSpec
КлассЭтот class (который реализует AlgorithmParameterSpec
интерфейс), определяет набор параметров, используемых с алгоритмом RC2.
Метод | Описание |
---|---|
boolean equals(Object obj) |
Тесты для равенства между указанным объектом и этим объектом. |
int getEffectiveKeyBits() |
Возвращает эффективный размер ключа в битах. |
byte[] getIV() |
Возвращает IV или нуль, если этот набор параметра не содержит IV. |
int hashCode() |
Вычисляет значение хэш-кода для объекта. |
RC5ParameterSpec
КлассЭтот class (который реализует AlgorithmParameterSpec
интерфейс), определяет набор параметров, используемых с алгоритмом RC5.
Метод | Описание |
---|---|
boolean equals(Object obj) |
Тесты для равенства между указанным объектом и этим объектом. |
byte[] getIV() |
Возвращает IV или нуль, если этот набор параметра не содержит IV. |
int getRounds() |
Возвращает число раундов. |
int getVersion() |
Возвращает версию. |
int getWordSize() |
Возвращает размер слова в битах. |
int hashCode() |
Вычисляет значение хэш-кода для объекта. |
DHParameterSpec
КлассЭтот class (который реализует AlgorithmParameterSpec
интерфейс), определяет набор параметров, используемых с алгоритмом Diffie-Hellman.
Метод | Описание |
---|---|
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
классы, есть два возможных сценария, один из которых требует, чтобы Вы реализовали свои собственные ключевые спецификации:
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
) объект, соответственно.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
.
Этот class (который реализует KeySpec
Интерфейс), определяет открытый ключ DSA с его связанными параметрами. У этого есть следующие методы:
Метод в DSAPublicKeySpec |
Описание |
---|---|
public BigInteger getY() |
возвращает открытый ключ y. |
public BigInteger getP() |
Возвращает главный p. |
public BigInteger getQ() |
Возвращает субстандартный q. |
public BigInteger getG() |
Возвращает основной г. |
Эти методы возвращают открытый ключ y
, и параметры алгоритма DSA, используемые, чтобы вычислить ключ: начало p
, субстандартное q
, и основа g
.
Этот class (который реализует KeySpec
Интерфейс), определяет закрытый ключ RSA. У этого есть следующие методы:
Метод в RSAPrivateKeySpec |
Описание |
---|---|
public BigInteger getModulus() |
Возвращает модуль. |
public BigInteger getPrivateExponent() |
Возвращает частную экспоненту. |
Эти методы возвращают модуль RSA n
и частная экспонента d
значения, которые составляют закрытый ключ RSA.
Этот 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 предназначается для эффективности.
Этот class (который реализует KeySpec
Интерфейс), определяет открытый ключ RSA. У этого есть следующие методы:
Метод в RSAPublicKeySpec |
Описание |
---|---|
public BigInteger getModulus() |
Возвращает модуль. |
public BigInteger getPublicExponent() |
Возвращает общедоступную экспоненту. |
Эти методы возвращают модуль RSA n
и общедоступная экспонента e
значения, которые составляют открытый ключ RSA.
Этот абстрактный 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".
Этот 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
) одним из следующих способов:
SecretKeySpec
, который уже реализует javax.crypto.SecretKey
интерфейс. Вы передаете (необработанные) ключевые байты и имя алгоритма секретного ключа, связанного с Вашим ключевым генератором с SecretKeySpec
конструктор. Этот подход полезен, если базовые (необработанные) ключевые байты могут быть представлены как байтовый массив и не иметь никаких основных параметров, связанных с ними.Следующая информация применяется к провайдерам, кто предоставляет алгоритм, который не перечисляется как один из стандартных алгоритмов в Приложении A Справочника Архитектуры Криптографии Java.
Иногда 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");
Если 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, являются следующим:
Ниже сокращенная версия 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; } }); } }
Ниже сокращенная версия 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; } }); } }
Ниже часть 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