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

Расширение Защищенного сокета Java™ (JSSE)
Справочник

для Платформы Java Standard Edition 7


Введение
Особенности и преимущества
API Стандарта JSSE
Провайдер SunJSSE
Связанная Документация
Сроки и Определения
Уровень защищенных сокетов (SSL) Краткий обзор Протокола
Почему SSL Использования?
Как SSL Работает
Ключевые Классы
Отношение Между Классами
Базовые Классы и Интерфейсы
SocketFactory и Классы ServerSocketFactory
SSLSocketFactory и Классы SSLServerSocketFactory
SSLSocket и Классы SSLServerSocket
Неблокирование ввода-вывода с SSLEngine
SSLSession и Интерфейсы ExtendedSSLSession
Класс HttpsURLConnection
Классы поддержки и Интерфейсы
Класс SSLContext
Интерфейс TrustManager
Класс TrustManagerFactory
Интерфейс X509TrustManager
Класс X509ExtendedTrustManager
Интерфейс KeyManager
Класс KeyManagerFactory
Интерфейс X509KeyManager
Класс X509ExtendedKeyManager
Отношения между TrustManagers и KeyManagers
Вторичные Классы Поддержки и Интерфейсы
Класс SSLParameters
Интерфейс SSLSessionContext
Интерфейс SSLSessionBindingListener
Класс SSLSessionBindingEvent
Интерфейс HandShakeCompletedListener
Класс HandShakeCompletedEvent
Интерфейс HostnameVerifier
Класс X509Certificate
Интерфейс AlgorithmConstraints
Предыдущий (JSSE 1.0.x) Классы Реализации и Интерфейсы
Настройка JSSE
Каталог Установки <дом Java>
Настройка
Безопасность Транспортного уровня (TLS) Проблема Пересмотра
Введение
Поэтапный Подход к Устранению Этой Проблемы
Описание Фазы 2 Фиксирует
Обходные решения/Альтернативы к Пересмотру SSL/TLS
Детали реализации
Описание Фазы 1 Фиксирует
JCE и Аппаратные средства Поддержка Acceleration/Smartcard
Использование JCE
Аппаратные Акселераторы
Сконфигурируйте JSSE, чтобы использовать Smartcards в качестве Keystore и Trust Stores
Многократный и Динамический Keystores
Комплекты Шифра Kerberos
Требования Kerberos
Равноправная информация об Идентификационных данных
Менеджер безопасности

Дополнительные Форматы Keystore (PKCS12)

Поиск и устранение неисправностей
Проблемы конфигурации
Утилиты отладки
Примеры кода
Преобразование Незащищенного сокета к Защищенному сокету
Выполнение Примера кода JSSE
Создание Keystore, чтобы Использовать с JSSE
Приложение A: Стандартные имена

Приложение B: Провайдер Pluggability


Введение

К данным, которые перемещаются через сеть, может легко получить доступ кто-то, кто не предполагаемый получатель. Когда данные включают частную информацию, такую как пароли и номера кредитной карточки, шаги должны быть сделаны, чтобы сделать данные непонятными к несанкционированным сторонам. Также важно гарантировать, что данные не были изменены, или преднамеренно или неумышленно, во время транспорта. Уровень защищенных сокетов (SSL) и Безопасность Транспортного уровня (TLS), протоколы были разработаны, чтобы помочь защитить конфиденциальность и целостность данных, в то время как это передается через сеть.

Расширение Защищенного сокета Java (JSSE) включает безопасной интернет-связи. Это служит основой и реализацией для версии Java SSL и протоколов TLS и включает функциональность для шифрования данных, аутентификации сервера, целостности сообщения, и дополнительной аутентификации клиента. Используя JSSE, разработчики могут предусмотреть безопасный проход данных между клиентом и сервером, выполняющим любой протокол приложения, такой как Гипертекстовый Протокол передачи (HTTP), Telnet, или FTP, по TCP/IP. (Для введения в SSL см. Уровень защищенных сокетов (SSL) Краткий обзор Протокола.)

Абстрагируя сложные базовые алгоритмы безопасности и "квитируя" механизмы, JSSE минимизирует риск создания тонких, но опасных уязвимостей системы обеспечения безопасности. Кроме того это упрощает разработку приложений, служа стандартным блоком, который разработчики могут интегрировать непосредственно в их приложения.

JSSE был ранее дополнительным пакетом к Java 2 SDK, Standard Edition (J2SDK), v 1.3. JSSE был интегрирован в Java Standard Edition Комплект разработчика, запускающийся с J2SDK 1.4.

JSSE обеспечивает и прикладной программный интерфейс (API) платформа и реализацию того API. API JSSE добавляет "базовые" сетевые и криптографические службы, определенные java.security и java.net пакеты, обеспечивая расширенные сетевые классы сокета, доверяйте менеджерам, манипулируйте менеджеров, SSLContexts, и платформу фабрики сокета для того, чтобы инкапсулировать поведение создания сокета. Поскольку API сокета были основаны на модели ввода-вывода блокирования, в JDK 5.0, неблокировании SSLEngineAPI был представлен, чтобы позволить реализациям выбирать свои собственные методы ввода-вывода.

API JSSE способен к поддержке версий 2.0 и 3.0 SSL и Безопасности Транспортного уровня (TLS) 1.0. Эти протоколы системы защиты инкапсулируют нормальный двунаправленный потоковый сокет, и API JSSE добавляет прозрачную поддержку аутентификации, шифрования, и защиты целостности. Реализация JSSE, поставленная с JRE Oracle, поддерживает SSL 3.0 и TLS 1.0. Это не реализует SSL 2.0.

Как упомянуто выше, JSSE является компонентом безопасности Java SE 6 платформ, и основан на тех же самых принципах разработки, найденных в другом месте в Архитектуре Криптографии Java (JCA) платформа. Эта платформа для связанных с криптографией компонентов безопасности позволяет им иметь независимость реализации и, когда бы ни было возможно, независимость алгоритма. JSSE использует ту же самую архитектуру "провайдера", определенную в JCA.

Другие компоненты безопасности в Java SE 6 платформ включают Службу Аутентификации и авторизации Java (JAAS), и Средства обеспечения безопасности Java. JSSE охватывает многие из тех же самых понятий и алгоритмов как те в JCE, но автоматически применяет их под простым потоковым API сокета.

API JSSE были разработаны, чтобы позволить другому протоколу SSL/TLS и Инфраструктуре управления открытыми ключами (PKI) реализации быть включенным легко. Разработчики могут также обеспечить альтернативную логику для того, чтобы она определила, нужно ли удаленным узлам доверять или что ключевой материал аутентификации должен быть отправлен удаленному узлу.

Особенности и преимущества

JSSE включает следующие важные функции:

Криптографическая Функциональность, Доступная С JSSE
Криптографический Algorithm1 Криптографический Процесс Длины ключа (Биты)
RSA Аутентификация и ключевой обмен 512 и больше
RC4 Шифрование больших объемов данных 128
128 (40 эффективный)
DES Шифрование больших объемов данных 64 (56 эффективный)
64 (40 эффективный)
Тройной DES Шифрование больших объемов данных 192 (112 эффективный)
AES Шифрование больших объемов данных 2562
128
Diffie-Hellman Согласование ключей 1024
512
DSA Аутентификация 1024

1Note: реализация SunJSSE использует Расширение Криптографии Java (JCE) для всех его криптографических алгоритмов.

2Cipher комплекты, которые используют AES_256, требуют установки Неограниченных Файлов Политики Юрисдикции Силы JCE. См. Java Страница Загрузки SE.

API Стандарта JSSE

Стандартный API JSSE, доступный в javax.net и javax.net.ssl пакеты, покрытия:

SunJSSE Провайдер

Реализация Oracle Java SE включает провайдера JSSE, названного"SunJSSE", который прибывает предварительно установленный и предварительно зарегистрированный в JCA. Этот провайдер предоставляет следующие криптографические службы:

Больше информации об этом провайдере доступно в разделе SunJSSE.

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

Документация Расширения Защищенного сокета Java

Документация Безопасности Платформы Java

Проблемы экспорта, Связанные с Криптографией

Для получения информации об американских политиках шифрования обратитесь к этим Веб-сайтам:

Документация криптографии

Онлайновые ресурсы:

Книги:

Документация Уровня защищенных сокетов

Онлайновые ресурсы:

Книги:

Сроки и Определения

Есть несколько сроков, касающихся криптографии, которые используются в пределах этого документа. Этот раздел дает определение некоторым из этих слов.

Аутентификация

Аутентификация является процессом подтверждения идентификационных данных стороны, с кем каждый связывается.

Комплект шифра

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

Сертификат

Сертификат является в цифровой форме подписанным заявлением, ручающимся за идентификационные данные и открытый ключ объекта (человек, компания, и т.д.). Сертификаты могут или быть самоподписаны или выпущены Центром сертификации (CA). Центры сертификации являются объектами, которые доверяются, чтобы выпустить допустимые сертификаты для других объектов. Известная АВАРИЯ включает VeriSign, Поручает, и GTE CyberTrust. X509 является общим форматом сертификата, и ими может управлять keytool JDK.

Криптографическая хеш-функция

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

Провайдер криптографических служб

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

Цифровая подпись

Цифровая подпись является цифровым эквивалентом рукописной подписи. Это используется, чтобы гарантировать, что данные, переданные по сети, были отправлены тем, кто бы ни утверждает, что отправил это и что данные не были изменены в пути. Например, RSA-на-основе цифровая подпись вычисляется первыми вычислениями криптографического хеша данных и затем шифрования хеша с закрытым ключом отправителя.

Шифрование и Дешифрование

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

Протокол квитирования

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

Согласование ключей

Согласование ключей является методом, которым две стороны сотрудничают, чтобы установить общий ключ. Каждая сторона генерирует некоторые данные, которые передаются. Эти две части данных тогда объединяются, чтобы генерировать ключ. Только те, которые содержат надлежащие частные данные инициализации, будут в состоянии получить заключительный ключ. Diffie-Hellman (DH) является наиболее распространенным примером алгоритма согласования ключей.

Ключевой Exchange

Одна сторона генерирует симметричный ключ и шифрует его использующий открытый ключ коллеги (обычно RSA). Данные тогда передаются к коллеге, кто тогда дешифрует ключ, используя его соответствующий закрытый ключ.

Манипулируйте менеджеров и Доверяйте менеджерам

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

Keystores и Truststores

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

Вообще говоря, keystore информация может быть сгруппирован в две различных категории: ключевые записи и доверяли записям сертификата. Ключевая запись состоит из идентификационных данных объекта и его закрытого ключа, и может использоваться для множества криптографических целей. Напротив, доверяемая запись сертификата только содержит открытый ключ в дополнение к идентификационным данным объекта. Таким образом доверяемая запись сертификата не может использоваться, где закрытый ключ требуется, такой как в a javax.net.ssl.KeyManager. В реализации JDK "JKS" keystore может содержать и ключевые записи и доверял записям сертификата.

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

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

Может быть полезно иметь два различных keystore файла: один содержащий только Ваши ключевые записи, и другой содержащий Ваши доверяемые записи сертификата, включая Центр сертификации (CA) сертификаты. Прежний содержит частную информацию, в то время как последний не делает. Используя два различных файла вместо единственного keystore файла предусматривает более чистое разделение логического различия между Вашими собственными сертификатами (и соответствующие закрытые ключи) и сертификатами других. Вы могли обеспечить больше защиты для своих закрытых ключей, если Вы храните их в keystore с ограниченным доступом, обеспечивая доверяемые сертификаты в более публично доступном keystore если нужно.

Код аутентификации сообщений

Код аутентификации сообщений (MAC) обеспечивает способ проверить целостность информации, переданной или сохраненный в ненадежном носителе, основанном на секретном ключе. Как правило, MACs используется между двумя сторонами, которые совместно используют секретный ключ, чтобы проверить информации, переданной между этими сторонами.

Механизм MAC, который основан на криптографических хеш-функциях, упоминается как HMAC. HMAC может использоваться с любой криптографической хеш-функцией, такой как сообщение Обзор 5 (MD5) и Безопасный Хеш-алгоритм (SHA), в комбинации с секретом совместно использованный ключ. HMAC определяется в RFC 2104.

Шифрование с открытым ключом

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

Протокол записи

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

Криптография Секретного ключа

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

Сеанс

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

Доверительные менеджеры

См. Ключевых менеджеров и Доверяйте менеджерам.

База доверенных сертификатов

См. Keystores и Базы доверенных сертификатов.

Уровень защищенных сокетов (SSL) Краткий обзор Протокола

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

SSL обеспечивает безопасное улучшение для стандартного протокола сокетов TCP/IP, используемого для интернет-связи. Как показано в следующей таблице, "Стек Протокола TCP/IP с SSL," уровень защищенных сокетов добавляется между транспортным уровнем и прикладным уровнем в стандартном стеке протокола TCP/IP. Приложение, обычно используемое с SSL, является Гипертекстовым Протоколом передачи (HTTP), протокол для интернет-Веб-страниц. Другие приложения, такие как Протокол передачи Новостей Сети (NNTP), Telnet, Легкий Протокол Доступа Каталога (LDAP), Интерактивный Протокол Доступа сообщения (IMAP), и Протокол Передачи файлов (FTP), могут быть использованы с SSL также.

Отметьте: нет в настоящий момент никакого стандарта для безопасного FTP.

Стек Протокола TCP/IP с SSL
Уровень TCP/IP Протокол
Прикладной уровень HTTP, NNTP, Telnet, FTP, и т.д.
Уровень защищенных сокетов SSL
Транспортный уровень TCP
Интернет-Уровень IP

SSL был разработан Netscape в 1994, и с вводом от интернет-сообщества, развился, чтобы стать стандартом. Это теперь является объектом управления Международной организации по стандартизации, Инженерной группы по развитию интернета (IETF). IETF переименовал SSL к Безопасности Транспортного уровня (TLS), и выпустил первую спецификацию, версию 1.0, в январе 1999. TLS 1.0 является скромным обновлением до новой версии SSL, версии 3.0. Различия между SSL 3.0 и TLS 1.0 незначительны.

Почему SSL Использования?

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

SSL решает каждую из этих проблем. Это решает первую проблему, дополнительно позволяя каждую из двух связывающихся сторон гарантировать идентификационные данные другой стороны в процессе, названном аутентификацией. Как только стороны аутентифицируются, SSL обеспечивает зашифрованное соединение между этими двумя сторонами для безопасной передачи сообщения. Шифрование передачи между этими двумя сторонами обеспечивает конфиденциальность и поэтому решает вторую проблему. Алгоритмы шифрования, используемые с SSL, включают безопасную хеш-функцию, которая подобна контрольной сумме. Это гарантирует, что данные не изменяются в пути. Безопасная хеш-функция решает третью проблему целостности данных.

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

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

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

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

Как SSL Работает

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

Криптографические Процессы

Основная цель криптографии состоит в том, чтобы мешать несанкционированной третьей стороне получать доступ и понимать частное общение между двумя сторонами. Не всегда возможно ограничить весь несанкционированный доступ к данным, но частные данные могут быть сделаны непонятными к несанкционированным сторонам посредством процесса шифрования. Шифрование использует сложные алгоритмы, чтобы преобразовать исходное сообщение, или открытый текст, к закодированному сообщению, названному шифрованным текстом. Алгоритмы, используемые, чтобы зашифровать и дешифровать данные, которые передаются по сети, обычно прибывшей в две категории: криптография секретного ключа и шифрование с открытым ключом. Эти формы криптографии объясняются в следующих подразделах.

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

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

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

Криптография Секретного ключа

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

Одной из больших проблем с криптографией секретного ключа является тыловая проблема того, как получить ключ от одной стороны до другого, не предоставляя доступ атакующему. Если Элис и Боб защищают их данные с криптографией секретного ключа, и если Чарли получает доступ к их ключу, Чарли может понять любые секретные сообщения, которые он прерывает между Элис и Бобом. Мало того, что Чарли может дешифровать сообщения Элис и Боба, но и он может также притвориться, что он - Элис, и отправьте зашифрованные данные, чтобы Качнуться. Боб не будет знать, что сообщение прибыло от Чарли, не Элис.

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

Криптографию секретного ключа также вызывают криптографией с симметричными шифрами, потому что тот же самый ключ используется, чтобы и зашифровать и дешифровать данные. Известные криптографические алгоритмы секретного ключа включают Стандарт шифрования данных (DES), DES тройной силы (3DES), Шифр Rivest 2 (RC2), и Шифр Rivest 4 (RC4).

Шифрование с открытым ключом

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

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

Если Элис шифрует сообщение, используя ее закрытый ключ и передается, зашифрованное сообщение, чтобы Качнуться, Качнуться может убедиться, что данные, которые он получает, прибывают от Элис; если Боб может дешифровать данные с открытым ключом Элис, сообщение, должно быть, было зашифровано Элис с ее закрытым ключом, и только у Элис есть закрытый ключ Элис. Проблема состоит в том, что кто-либо еще может считать сообщение также, потому что открытый ключ Элис общедоступен. В то время как этот сценарий не учитывает безопасную передачу данных, он действительно обеспечивает основание для цифровых подписей. Цифровая подпись является одним из компонентов сертификата с открытым ключом, и используется на SSL, чтобы аутентифицировать клиент или сервер. Сертификаты с открытым ключом и цифровые подписи описываются в более поздних разделах.

Шифрование с открытым ключом также вызывают криптографией с асимметричными шифрами, потому что различные ключи используются, чтобы зашифровать и дешифровать данные. Известным криптографическим алгоритмом с открытым ключом, часто используемым с SSL, является Ривест Шамир Адлемен (RSA) алгоритм. Другой алгоритм с открытым ключом, используемый с SSL, который специально разработан для обмена секретного ключа, является Diffie-Hellman (DH) алгоритм. Шифрование с открытым ключом требует обширных вычислений, делая это очень медленный. Это поэтому обычно используется только для того, чтобы зашифровать маленькие части данных, такие как секретные ключи, а не для объема зашифрованной передачи данных.

Сравнение Между Секретным ключом и Шифрованием с открытым ключом

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

Сертификаты С открытым ключом

Сертификат с открытым ключом обеспечивает безопасный путь к объекту, чтобы передать его открытый ключ, который будет использоваться в криптографии с асимметричными шифрами. Сертификат с открытым ключом избегает следующей ситуации: если Чарли создает свой собственный и закрытый ключ с открытым ключом, он может утверждать, что он - Элис, и отправьте его открытый ключ, чтобы Качнуться. Боб будет в состоянии связаться с Чарли, но Боб будет думать, что отправляет свои данные Элис.

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

Сертификат с открытым ключом содержит несколько полей, включая:

Если Боб только примет открытый ключ Элис как допустимый, когда она отправит его в сертификате с открытым ключом, то Боба не будут дурачить в отправку секретной информации Чарли, когда Чарли подменяет Элис.

Многократные сертификаты могут быть соединены в цепочке сертификата. Когда цепочка сертификата используется, первый сертификат всегда является сертификатом отправителя. Следующим является сертификат об объекте, который выпустил сертификат отправителя. Если есть больше сертификатов в цепочке, каждый - те из полномочий, которые выпустили предыдущий сертификат. Заключительный сертификат в цепочке является сертификатом для корневого CA. Корневой CA является общедоступным центром сертификации, которому широко доверяют. Информация для нескольких корневых АВАРИЙ обычно хранится в Интернет-браузере клиента. Эта информация включает открытый ключ CA. Известная АВАРИЯ включает VeriSign, Поручает, и GTE CyberTrust.

Криптографические хеш-функции

Когда отправка зашифрованные данные, SSL обычно использует криптографическую хеш-функцию, чтобы гарантировать целостность данных. Хеш-функция препятствует тому, чтобы Чарли вмешался в данные, которые Элис отправляет Бобу.

Криптографическая хеш-функция подобна контрольной сумме. Основное различие - то, что, в то время как контрольная сумма разрабатывается, чтобы обнаружить случайные изменения в данных, криптографическая хеш-функция разрабатывается, чтобы обнаружить преднамеренные изменения. Когда данные обрабатываются криптографической хеш-функцией, маленькая строка битов, известных как хеш, сгенерирована. Малейшее изменение к сообщению обычно производит большое изменение в получающемся хеше. Криптографическая хеш-функция не требует криптографического ключа. Две хеш-функции, часто используемые с SSL, являются сообщением Обзор 5 (MD5) и Защищают Хеш-алгоритм (SHA). SHA был предложен американским Национальным Институтом Науки и техники (NIST).

Код аутентификации сообщений

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

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

Цифровые подписи

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

Процесс SSL

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

Три основных цели квитирования SSL:

Согласование Комплекта Шифра

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

Аутентификация Сервера

На SSL шаг аутентификации является дополнительным, но в примере транзакции электронной коммерции по сети, клиент будет обычно хотеть аутентифицировать сервер. Аутентификация сервера позволяет клиенту убеждаться, что сервер представляет объект, что клиент полагает, что сервер представляет.

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

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

Отправка Зашифрованных Данных

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

Протокол SSL

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

"SSL передает" число, которое следует за шоу последовательность сообщений, которыми обмениваются в квитировании SSL. Сообщения, которые отправляются только в определенных ситуациях, отмечаются как дополнительные. Каждое из сообщений SSL описывается в следующем числе:

Последовательностью сообщений обмениваются в квитировании SSL.


Сообщения SSL отправляются в следующем порядке:

  1. Клиент привет - клиент отправляет информацию о сервере включая самую высокую версию SSL, который это поддерживает и список комплектов шифра, которые это поддерживает. (TLS 1.0 обозначается как SSL 3.1.) Информация о комплекте шифра включает криптографические алгоритмы и размеры ключа.
  2. Сервер привет - сервер выбирает самую высокую версию SSL и лучший комплект шифра, что оба поддержка клиента и сервера и отправляют эту информацию клиенту.
  3. Сертификат - сервер отправляет клиенту сертификат или цепочку сертификата. Цепочка сертификата обычно начинается с сертификата сервера с открытым ключом и заканчивается корневым сертификатом центра сертификации. Это сообщение является дополнительным, но используется всякий раз, когда аутентификация сервера требуется.
  4. Запрос сертификата - Если сервер должен аутентифицировать клиент, он отправляет клиенту запрос сертификата. В Интернет-приложениях редко отправляется это сообщение.
  5. Ключевой обмен сервера - сервер отправляет клиенту ключевое сообщение обмена сервера, когда информация с открытым ключом, отправленная в сообщении 3 выше, не достаточна для ключевого обмена. Например, в ciphersuites, основанном на Diffie-Hellman, это сообщение содержит открытый ключ DH сервера.
  6. Сервер, привет сделанный - сервер говорит клиенту, что это заканчивается с его начальными сообщениями согласования.
  7. Сертификат - Если запросы к серверу сертификат от клиента в сообщении 4, клиент отправляет его цепочку сертификата, как сервер сделал в сообщении 3.

    Отметьте: Только несколько приложений Интернет-сервера просят сертификат от клиента.

  8. Клиентский ключевой обмен - клиент генерирует информацию, используемую, чтобы создать ключ, чтобы использовать для симметричного шифрования. Для RSA клиент тогда шифрует эту ключевую информацию с открытым ключом сервера и отправляет это серверу. Для ciphersuites, основанного на Diffie-Hellman, это сообщение содержит открытый ключ DH клиента.
  9. Сертификат проверяет - Это сообщение отправляется, когда клиент представляет сертификат как ранее объяснено. Его цель состоит в том, чтобы позволить серверу завершать процесс аутентификации клиента. Когда это сообщение используется, клиент отправляет информацию, что это в цифровой форме подписывает использование криптографической хеш-функции. Когда сервер дешифрует эту информацию с открытым ключом клиента, сервер в состоянии аутентифицировать клиент.
  10. Спецификация шифра изменения - клиент отправляет сообщение, говоря сервер измениться на зашифрованный режим.
  11. Законченный - клиент говорит серверу, что это готово к безопасной передаче данных начаться.
  12. Спецификация шифра изменения - сервер отправляет сообщение, говоря клиенту измениться на зашифрованный режим.
  13. Законченный - сервер говорит клиенту, что это готово к безопасной передаче данных начаться. Это - конец квитирования SSL.
  14. Зашифрованные данные - клиент и сервер передают использование симметричного алгоритма шифрования и криптографической хеш-функции, согласованной в сообщениях 1 и 2, и использовании секретного ключа что клиент, отправленный серверу в сообщении 8. В это время может быть пересмотрено квитирование. См. следующий раздел для деталей.
  15. Сообщения о закрытии - В конце соединения, каждая сторона отправит a close_notify message сообщать коллеге, что соединение закрывается.

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

Квитирование Снова (Пересмотр)

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

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

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

Отметьте, что дефект протокола, связанный с пересмотром, был найден в 2009. Протокол и Java реализация SE были оба фиксированы. Для получения дополнительной информации см. Безопасность Транспортного уровня (TLS) Проблема Пересмотра.

Выбор Комплекта шифра и Удаленная Проверка Объекта

Протоколы SSL/TLS определяют определенную серию шагов, чтобы гарантировать "защищенное" соединение. Однако, выбор комплекта шифра будет непосредственно воздействовать на тип безопасности, которой обладает соединение. Например, если анонимный комплект шифра будет выбран, то у приложения не будет никакого способа проверить идентификационные данные удаленной коллеги. Если комплект без шифрования выбирается, то конфиденциальность данных не может быть защищена. Дополнительно, протоколы SSL/TLS не определяют, что полученные учетные данные должны соответствовать тем, которых коллега, как могли бы ожидать, отправит. Если бы соединение было так или иначе перенаправлено к коллеге жулика, но представленные учетные данные жулика были приемлемые основанный на текущем доверительном материале, то соединение считали бы допустимым.

При использовании сырых данных SSLSockets/SSLEngines следует всегда проверять учетные данные коллеги прежде, чем отправить любые данные. SSLSocket и SSLEngine классы автоматически не проверяют, что имя хоста в URL соответствует имя хоста в учетных данных коллеги. Приложение могло быть использовано со спуфингом URL, если имя хоста не проверяется.

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

SSL и Ссылки TLS

Для списка ресурсов, содержащих больше информации о SSL, см. Документацию Уровня защищенных сокетов.

Ключевые Классы

Отношение Между Классами

Чтобы связаться надежно, обе стороны соединения должны быть поддерживающими SSL. В API JSSE классы конечной точки соединения SSLSocket и SSLEngine. В схеме ниже, главные классы, используемые, чтобы создать SSLSocket/SSLEngines размечаются в логическом упорядочивании.

схема классов, используемых, чтобы создать SSLSockets/SSLEngines


SSLSocket создается любой SSLSocketFactory или SSLServerSocket принятие входящего соединения. (Поочередно, SSLServerSocket создается SSLServerSocketFactory.) Оба SSLSocketFactory и SSLServerSocketFactory объекты создаются SSLContext. SSLEngine создается непосредственно SSLContext, и полагается на приложение, чтобы обработать весь ввод-вывод.


ВАЖНОЕ ПРИМЕЧАНИЕ: При использовании сырых данных SSLSockets/SSLEngines следует всегда проверять учетные данные коллеги прежде, чем отправить любые данные. SSLSocket/SSLEngine классы автоматически не проверяют, например, что имя хоста в URL соответствует имя хоста в учетных данных коллеги. Приложение могло быть использовано со спуфингом URL, если имя хоста не проверяется.

Есть два способа получить и инициализировать SSLContext:

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

Базовые Классы и Интерфейсы

Базовые классы JSSE являются частью javax.net и javax.net.ssl пакеты.

SocketFactory и ServerSocketFactory Классы

Краткий обзор javax.net.SocketFactory класс используется, чтобы создать сокеты. Это должно быть разделено на подклассы другими фабриками, которые создают определенные подклассы сокетов и таким образом обеспечивают общие рамки для добавления общедоступной функциональности на уровне сокета. (См., например, SSLSocketFactory.)

javax.net.ServerSocketFactory класс походит SocketFactory класс, но используется определенно для того, чтобы создать сокеты сервера.

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

SSLSocketFactory и SSLServerSocketFactory Классы

A javax.net.ssl.SSLSocketFactory действия как фабрика для того, чтобы создать защищенные сокеты. Этот класс является абстрактным подклассом javax.net.SocketFactory.

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

javax.net.ssl.SSLServerSocketFactory класс походит SSLSocketFactory класс, но используется определенно для того, чтобы создать сокеты сервера.

Получение SSLSocketFactory

Есть три основных способа получить SSLSocketFactory:

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

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

Можно создать новые экземпляры фабрики сокета или реализовывая Ваш собственный подкласс фабрики сокета или при использовании другого класса, который действует как фабрика для фабрик сокета. Один пример такого класса SSLContext, которому предоставляют реализацию JSSE как основанный на провайдере класс конфигурации.

SSLSocket и SSLServerSocket Классы

javax.net.ssl.SSLSocket класс является подклассом стандартного Java java.net.Socket класс. Это поддерживает все стандартные методы сокета и добавляет дополнительные методы, определенные для защищенных сокетов. Экземпляры этого класса инкапсулируют SSLContext под которым они создавались. Есть API, чтобы управлять созданием сеансов защищенного сокета для экземпляра сокета, но доверительное и управление ключами непосредственно не представляются.

javax.net.ssl.SSLServerSocket класс походит SSLSocket класс, но используется определенно для того, чтобы создать сокеты сервера.

Чтобы предотвратить равноправный спуфинг, следует всегда проверять учетные данные, представленные SSLSocket.

Примечание реализации: из-за сложности SSL и протоколов TLS, трудно предсказать, являются ли входящие байты на соединении квитированием или данными приложения, и как те данные могли бы влиять на текущее состояние соединения (даже то, чтобы заставлять процесс блокировать). В реализации Oracle JSSE, available() метод на объекте, полученном SSLSocket.getInputStream() еще возвращает количество числа байтов данных приложения, успешно дешифрованных от соединения SSL, но чтения приложением.

Получение SSLSocket

Экземпляры SSLSocket может быть получен двумя способами. Во-первых, SSLSocket может быть создан экземпляром SSLSocketFactory через один из нескольких createSocket методы на том классе. Второй способ получить SSLSockets через accept метод на SSLServerSocket класс.

Неблокирование ввода-вывода с SSLEngine

SSL/TLS становится все более и более популярным. Это используется в большом разнообразии приложений через широкий диапазон вычислительных платформ и устройств. Наряду с этой популярностью прибывает требования использовать это с различным вводом-выводом и моделями потоков, чтобы удовлетворить производительность приложений, масштабируемость, место, и другие требования. Есть требования использовать это с блокированием и неблокированием каналов ввода-вывода, асинхронного ввода-вывода, произвольных потоков входа и выхода, и буферов байта. Есть требования использовать это в хорошо масштабируемых, критических по отношению к производительности средах, требуя управления тысячами сетевых соединений.

До Java SE 5, API JSSE, поддерживаемый только единственная транспортная абстракция: основанные на потоке сокеты через SSLSocket. В то время как это было достаточно для многих приложений, это не удовлетворяло потребности приложений, которые должны использовать различный ввод-вывод или модели потоков. В 1.6.0, новая абстракция была представлена, чтобы позволить приложениям использовать протоколы SSL/TLS транспортным независимым способом, и таким образом освобождение приложений, чтобы выбрать транспорт и вычислительные модели, которые лучше всего удовлетворяют их потребности. Мало того, что эта новая абстракция позволяет приложениям использовать каналы ввода-вывода неблокирования и другие модели ввода-вывода, она также размещает различные модели потоков. Это эффективно листы ввод-вывод и решения поточной обработки до приложения. Из-за этой гибкости приложение должно теперь управлять вводом-выводом и распараллеливающий (сложные темы в и себя), так же как иметь некоторое понимание протоколов SSL/TLS. Новая абстракция является поэтому усовершенствованным API: новички должны продолжать использовать SSLSocket.

Вновь прибывшие к API могут задаться вопросом, "Почему не только имеют SSLSocketChannel который расширяется java.nio.channels.SocketChannel?" Есть две главных причины:

Абстрагируя ввод-вывод и обрабатывая данные как потоки байтов, эти вопросы решаются, и новый API мог использоваться с любой существующей или будущей моделью ввода-вывода. В то время как это решение делает ввод-вывод и ЦП, обрабатывающий ответственность разработчиков, реализациям JSSE препятствуют быть неприменимыми из-за некоторой неконфигурируемой и/или неизменной внутренней детали.

Пользователи других API языка программирования Java, такие как JGSS и SASL заметят общие черты, в которых приложение также ответственно за перенос данных.

SSLEngine

Базовым классом в этой новой абстракции является javax.net.ssl.SSLEngine. Это инкапсулирует конечный автомат SSL/TLS и работает на входящих и исходящих буферах байта, предоставленных пользователем SSLEngine. Следующая схема иллюстрирует поток данных из приложения, к SSLEngine, к транспортному механизму, и назад.

SSLEngine

Приложение, показанное слева, предоставляет приложение (простой текст) данные в буфере приложения и передачах это к SSLEngine. SSLEngine обрабатывает данные, содержавшиеся в буфере, или любых данных квитирования, чтобы произвести SSL/TLS закодированные данные, и помещает это сетевой буфер, предоставленный приложением. Приложение тогда ответственно за использование соответствующего транспорта (показанный справа), чтобы отправить содержание сетевого буфера к его коллеге. После получения SSL/TLS закодированные данные от его коллеги (через транспорт), приложение помещает данные в сетевой буфер и передает это к SSLEngine. SSLEngine обрабатывает содержание сетевого буфера, чтобы произвести данные квитирования или данные приложения.

В целом, SSLEngine может быть в одном из пяти состояний.

  1. Создание - готовый быть сконфигурированным.
  2. Квитирование начальной буквы - выполняет аутентификацию и согласовывает коммуникационные параметры.
  3. Данные приложения - готовый к обмену приложения.
  4. Переквитирование - пересматривает коммуникационные параметры/аутентификацию; квитирование данных может быть смешано с данными приложения.
  5. Закрытие - готовый завершить работу соединения.
Эти пять состояний являются decribed более подробно в документации класса SSLEngine.

Начинание

Чтобы создать SSLEngine, Вы используете методы SSLContext.createSSLEngine(). Следует тогда сконфигурировать механизм, чтобы действовать как клиент или сервер, так же как установить другие параметры конфигурации такой как, какие комплекты шифра использовать и потребовать ли аутентификации клиента.

Вот пример, который создает SSLEngine. Отметьте, что имя сервера и номер порта не используются для того, чтобы связаться с сервером - весь транспорт является ответственностью приложения. Они - подсказки к провайдеру JSSE, чтобы использовать для кэширования сеанса SSL, и для основанных на Kerberos реализаций комплекта шифра, чтобы определить, какие учетные данные сервера должны быть получены.

import javax.net.ssl.*;
import java.security.*;

// Create/initialize the SSLContext with key material

char[] passphrase = "passphrase".toCharArray();

// First initialize the key and trust material.
KeyStore ksKeys = KeyStore.getInstance("JKS");
ksKeys.load(new FileInputStream("testKeys"), passphrase);
KeyStore ksTrust = KeyStore.getInstance("JKS");
ksTrust.load(new FileInputStream("testTrust"), passphrase);

// KeyManager's decide which key material to use.
KeyManagerFactory kmf =
    KeyManagerFactory.getInstance("SunX509");
kmf.init(ksKeys, passphrase);

// TrustManager's decide whether to allow connections.
TrustManagerFactory tmf =
    TrustManagerFactory.getInstance("SunX509");
tmf.init(ksTrust);

sslContext = SSLContext.getInstance("TLS");
sslContext.init(
    kmf.getKeyManagers(), tmf.getTrustManagers(), null);

// We're ready for the engine.
SSLEngine engine = sslContext.createSSLengine(hostname, port);

// Use as client
engine.setUseClientMode(true);

Генерирование и Обработка данных SSL/TLS

Два основных метода SSLEngine wrap() и unwrap() ответственны за генерирование и потребление сетевых данных соответственно. В зависимости от состояния SSLEngine эти данные могли бы быть квитированием или данными приложения.

У каждого SSLEngine есть несколько фаз во время его времени жизни. Прежде, чем данные приложения могут быть отправлены/получены, протокол SSL/TLS требует, чтобы квитирование установило криптографические параметры. Это квитирование требует серии назад и вперед шагов SSLEngine. Процесс SSL может обеспечить больше деталей о квитировании непосредственно.

Во время начального квитирования wrap() и unwrap() генерируют и используют данные квитирования, и приложение ответственно за перенос данных. wrap()/unwrap() последовательность повторяется, пока квитирование не заканчивается. Каждая работа SSLEngine генерирует SSLEngineResult, которого поле SSLEngineResult.HandshakeStatus используется, чтобы определить, какая работа должна произойти рядом с перемещением квитирование вперед.

Типичное квитирование могло бы быть похожим на это:

client SSL/TLS message HSStatus
wrap() ClientHello NEED_UNWRAP
unwrap() ServerHello/Cert/ServerHelloDone NEED_WRAP
wrap() ClientKeyExchange NEED_WRAP
wrap() ChangeCipherSpec NEED_WRAP
wrap() Finished NEED_UNWRAP
unwrap() ChangeCipherSpec NEED_UNWRAP
unwrap() Finished FINISHED
Теперь, когда квитирование является полными, дальнейшими звонками в wrap(), попытается использовать данные приложения и упаковывает это для транспорта. unwrap() делает попытку противоположности.

Чтобы отправить данные коллеге, приложение сначала снабжает данными, которые это хочет отправить SSLEngine через SSLEngine.wrap(), чтобы получить соответствующий SSL/TLS закодированные данные. Приложение тогда отправляет закодированные данные коллеге, используя ее выбранный транспортный механизм. Когда приложение получает SSL/TLS закодированные данные от коллеги через транспортный механизм, это снабжает этими данными к SSLEngine через SSLEngine.unwrap(), чтобы получить данные простого текста, отправленные коллегой.

Вот пример приложения SSL, которое использует неблокирование SocketChannel, чтобы связаться с его коллегой. (Это может быть сделано более устойчивым и масштабируемым при использовании Selector с неблокированием SocketChannel.) Следующий пример кода отправляет строке "hello" своей коллеге, кодируя это использующий SSLEngine, создаваемый в предыдущем примере. Это использует информацию от SSLSession, чтобы определить, как большой, чтобы сделать байт буферизует.

// Create a nonblocking socket channel
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress(hostname, port));

// Complete connection
while (!socketChannel.finishedConnect()) {
    // do something until connect completed
}

// Create byte buffers to use for holding application and encoded data
SSLSession session = engine.getSession();
ByteBuffer myAppData = ByteBuffer.allocate(session.getApplicationBufferSize());
ByteBuffer myNetData = ByteBuffer.allocate(session.getPacketBufferSize());
ByteBuffer peerAppData = ByteBuffer.allocate(session.getApplicationBufferSize());
ByteBuffer peerNetData = ByteBuffer.allocate(session.getPacketBufferSize());

// Do initial handshake
doHandshake(socketChannel, engine, myNetData, peerNetData);

myAppData.put("hello".getBytes());
myAppData.flip();

while (myAppData.hasRemaining()) {
    // Generate SSL/TLS encoded data (handshake or application data)
    SSLEngineResult res = engine.wrap(myAppData, myNetData);

    // Process status of call
    if (res.getStatus() == SSLEngineResult.Status.OK) {
        myAppData.compact();

        // Send SSL/TLS encoded data to peer
        while(myNetData.hasRemaining()) {
            int num = socketChannel.write(myNetData);
            if (num == -1) {
                // handle closed channel
            } else if (num == 0) {
                // no bytes written; try again later
            }
        }
    }

    // Handle other status:  BUFFER_OVERFLOW, CLOSED
    ...
}

Следующий код читает данные из того же самого неблокирования SocketChannel и извлекает данные простого текста из этого при использовании SSLEngine, создаваемого ранее. Каждая итерация этого кода может или, возможно, не производит данных простого текста, в зависимости от того, происходит ли квитирование.
// Read SSL/TLS encoded data from peer
int num = socketChannel.read(peerNetData);
if (num == -1) {
    // Handle closed channel
} else if (num == 0) {
    // No bytes read; try again ...
} else {
    // Process incoming data
    peerNetData.flip();
    res = engine.unwrap(peerNetData, peerAppData);

    if (res.getStatus() == SSLEngineResult.Status.OK) {
        peerNetData.compact();

        if (peerAppData.hasRemaining()) {
            // Use peerAppData
        }
    }
    // Handle other status:  BUFFER_OVERFLOW, BUFFER_UNDERFLOW, CLOSED
    ...
}

Состояние Операций

Чтобы указать на состояние механизма и что должно взять действие (я) приложение, методы SSLEngine.wrap() И SSLEngine.unwrap() возвращают экземпляр SSLEngineResult, как показано в предыдущих примерах. SSLEngineResult содержит две части информации о статусе: полное состояние механизма и состояние квитирования.

Возможные полные состояния представляются перечислением SSLEngineResult.Status. Некоторые примеры этого состояния включают OK, что означает, что не было никакой ошибки, и BUFFER_UNDERFLOW, что означает, что у входного буфера были недостаточные данные, указывая, что приложение должно получить больше данных из коллеги (например, читая больше данных из сети), и BUFFER_OVERFLOW, что означает, что у буфера вывода было недостаточное пространство, чтобы содержать результат, указывая, что приложение должно очистить или увеличить целевой буфер.

Вот пример того, как обработать BUFFER_UNDERFLOW и состояния BUFFER_OVERFLOW SSLEngine.unwrap(). Это использует SSLSession.getApplicationBufferSize() и SSLSession.getPacketBufferSize(), чтобы определить, как большой, чтобы сделать байт буферизует.

SSLEngineResult res = engine.unwrap(peerNetData, peerAppData);
switch (res.getStatus()) {

case BUFFER_OVERFLOW:
  // Maybe need to enlarge the peer application data buffer.
  if (engine.getSession().getApplicationBufferSize() >
          peerAppData.capacity()) {
      // enlarge the peer application data buffer
  } else {
        // compact or clear the buffer
  }
  // retry the operation
  break;

case BUFFER_UNDERFLOW:
  // Maybe need to enlarge the peer network packet buffer
  if (engine.getSession().getPacketBufferSize() >
          peerNetData.capacity()) {
      // enlarge the peer network packet buffer
  } else {
        // compact or clear the buffer
  }
  // obtain more inbound network data and then retry the operation
  break;

// Handle other status: CLOSED, OK
...
}

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

Наличие двух состояний на результат позволяет механизму указывать, что приложение должно предпринять два мер: один в ответ на квитирование и одно представление полного состояния wrap()/unwrap() метод. Например, механизм, как результат единственного вызова SSLEngine.unwrap(), мог бы возвратить SSLEngineResult.Status.OK, чтобы указать, что входные данные были обработаны успешно и SSLEngineResult.HandshakeStatus.NEED_UNWRAP, чтобы указать, что приложение должно получить больше SSL/TLS закодированные данные из коллеги и предоставить это к SSLEngine.unwrap() снова так, чтобы квитирование могло продолжаться. Как можно видеть, предыдущие примеры были значительно упрощены; они должны были бы быть расширены значительно, чтобы должным образом обработать все эти состояния.

Вот пример того, как обработать данные квитирования, проверяя квитирование состояния и полного состояния wrap()/unwrap() метод.

void doHandshake(SocketChannel socketChannel, SSLEngine engine,
        ByteBuffer myNetData, ByteBuffer peerNetData) throws Exception {

    // Create byte buffers to use for holding application data
    int appBufferSize = engine.getSession().getApplicationBufferSize();
    ByteBuffer myAppData = ByteBuffer.allocate(appBufferSize);
    ByteBuffer peerAppData = ByteBuffer.allocate(appBufferSize);

    // Begin handshake
    engine.beginHandshake();
    SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus();

    // Process handshaking message
    while (hs != SSLEngineResult.HandshakeStatus.FINISHED &&
        hs != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {

        switch (hs) {

        case NEED_UNWRAP:
            // Receive handshaking data from peer
            if (socketChannel.read(peerNetData) < 0) {
                // Handle closed channel
            }

            // Process incoming handshaking data
            peerNetData.flip();
            SSLEngineResult res = engine.unwrap(peerNetData, peerAppData);
            peerNetData.compact();
            hs = res.getHandshakeStatus();

            // Check status
            switch (res.getStatus()) {
            case OK :
                // Handle OK status
                break;

            // Handle other status: BUFFER_UNDERFLOW, BUFFER_OVERFLOW, CLOSED
            ...
            }
            break;

        case NEED_WRAP :
            // Empty the local network packet buffer.
            myNetData.clear();

            // Generate handshaking data
            res = engine.wrap(myAppData, myNetData);
            hs = res.getHandshakeStatus();

            // Check status
            switch (res.getStatus()) {
            case OK :
                myNetData.flip();

                // Send the handshaking data to peer
                while (myNetData.hasRemaining()) {
                    if (socketChannel.write(myNetData) < 0) {
                        // Handle closed channel
                    }
                }
                break;

            // Handle other status:  BUFFER_OVERFLOW, BUFFER_UNDERFLOW, CLOSED
            ...
            }
            break;

        case NEED_TASK :
            // Handle blocking tasks
            break;

        // Handle other status:  // FINISHED or NOT_HANDSHAKING
        ...
        }
    }

    // Processes after handshaking
    ...
}

Блокирование Задач

Во время квитирования SSLEngine мог бы встретиться с задачами, которые могли бы блокировать или занять много времени. Например, TrustManager, возможно, должен соединиться с удаленной службой проверки допустимости сертификата, или KeyManager, возможно, должен был бы запросить пользователя определять который сертификат использовать в качестве части аутентификации клиента. Чтобы сохранить природу неблокирования SSLEngine, когда механизм встречается с такой задачей, он возвратит SSLEngineResult.HandshakeStatus.NEED_TASK. После получения этого состояния приложение должно вызвать SSLEngine.getDelegatedTask(), чтобы получить задачу, и затем, используя модель потоков, подходящую для ее требований, обработать задачу. Приложение могло бы, например, получить поток (и) из пула потоков, чтобы обработать задачу (и), в то время как основной поток идет об обработке другого ввода-вывода.

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

if (res.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) {
    Runnable task;
    while ((task=engine.getDelegatedTask()) != null) {
        new Thread(task).start();
    }
}
Механизм блокирует будущее wrap/unwrap вызовы до всех выдающихся задач завершаются.

Завершение работы

Для аккуратного завершения работы соединения SSL/TLS протоколы SSL/TLS требуют передачи сообщений о закрытии. Поэтому, когда приложение делается с соединением SSL/TLS, оно должно сначала получить сообщения о закрытии из SSLEngine, затем передать их к коллеге, используя ее транспортный механизм, и наконец завершить работу транспортного механизма. Вот пример.
// Indicate that application is done with engine
engine.closeOutbound();

while (!engine.isOutboundDone()) {
    // Get close message
    SSLEngineResult res = engine.wrap(empty, myNetData);

    // Check res statuses

    // Send close message to peer
    while(myNetData().hasRemaining()) {
        int num = socketChannel.write(myNetData);
        if (num == -1) {
            // handle closed channel
        } else if (num == 0) {
            // no bytes written; try again later
        }
        myNetData().compact();
    }
}

// Close transport
socketChannel.close();
В дополнение к приложению, явно закрывающему SSLEngine, SSLEngine мог бы быть закрыт коллегой (через получение сообщения о закрытии, в то время как это обрабатывает данные квитирования), или SSLEngine, встречающимся с ошибкой, обрабатывая приложение или данные квитирования, обозначенные, бросая SSLException. В таких случаях приложение должно вызвать SSLEngine.wrap(), чтобы получить сообщение о закрытии и отправить это коллеге, пока SSLEngine.isOutboundDone() не возвращает true, как показано в предыдущем примере, или SSLEngineResult.getStatus () ЗАКРЫТЫЕ возвраты.

В дополнение к аккуратным завершениям работы могут также быть неаккуратные завершения работы, на которых разъединяется транспортный путь прежде, чем сообщениями о закрытии обмениваются. В предыдущих примерах приложение могло бы получить -1, пытаясь считать или записать в неблокирование SocketChannel. Когда Вы добираетесь до конца Ваших входных данных, следует вызвать engine.closeInbound (), который проверит с SSLEngine, что удаленная коллега закрылась чисто с точки зрения SSL/TLS, и затем приложение должно все еще попытаться завершить работу чисто при использовании процедуры выше. Очевидно, в отличие от SSLSocket, приложение, используя SSLEngine должно иметь дело с большим количеством изменений состояния, состояний и программирования, используя SSLEngine. Пожалуйста, см. NIO-на-основе сервер HTTPS для получения дополнительной информации о записи a SSLEngineНа основе приложение.

SSLSession и ExtendedSSLSession Интерфейсы

A javax.net.ssl.SSLSession представляет контекст защиты, согласованный между двумя коллегами SSLSocket или SSLEngine соединение. После того, как сеанс был расположен, он может быть совместно использован будущим SSLSocket или SSLEngine объекты соединялись между теми же самыми двумя коллегами.

В некоторых случаях параметры, согласованные во время квитирования, необходимы позже в квитировании, чтобы принять решения относительно доверия. Например, список алгоритмов действительной подписи мог бы ограничить типы сертификата, которые могут использоваться для аутентификации. В Java SE 7 выпусков, SSLSession может быть получен во время квитирования, вызывая getHandshakeSession() на SSLSocket или SSLEngine. Реализации TrustManager или KeyManager может использовать getHandshakeSession() получить информацию о параметрах сеанса, чтобы помочь им принять решения.

Полностью инициализированный SSLSession содержит комплект шифра, который будет использоваться для связи по защищенному сокету так же как неавторитетной подсказке относительно сетевого адреса удаленной коллеги, и информации управления, такой как время создания и последнего использования. Сеанс также содержит совместно используемый основной секрет, согласованный между коллегами, который используется, чтобы создать криптографические ключи для шифрования и гарантии целостности связи по SSLSocket или SSLEngine соединение. Значение этого основного секрета известно только базовой реализации защищенного сокета и не представляется через SSLSession API.

В Java SE 7 выпусков TLS 1.2 сеанса представляются ExtendedSSLSession, реализация SSLSession. ExtendedSSLSession добавляют методы, которые описывают алгоритмы подписи, которые поддерживаются локальной реализацией и коллегой.

Звонки в SSLSession.getPacketBufferSize() и SSLSession.getApplicationBufferSize() также используются, чтобы определить соответствующие буферные размеры, используемые SSLEngine.

Отметьте: протоколы SSL/TLS определяют, что реализации должны произвести пакеты, содержащие самое большее 16 Кбайт простого текста. Однако, некоторые реализации нарушают спецификацию и генерируют большие записи до 32 Кбайт. Если код SSLEngine.unwrap() обнаружит большие входящие пакеты, то буферные размеры, возвращенные SSLSession, будут обновлены динамически. Приложения должны всегда проверять BUFFER_OVERFLOW/BUFFER_UNDERFLOW состояния и увеличивать соответствующие буферы в случае необходимости. SunJSSE будет всегда отправлять стандартные совместимые записи на 16 Кбайт и позволять входящие записи на 32 Кбайта. (Также см. свойство System jsse.SSLEngine.acceptLargeFragments в Настройке для обходного решения.)

HttpsURLConnection Класс

https протокол подобен http, но https сначала устанавливает безопасный канал через сокеты SSL/TLS и затем проверяет идентификационные данные коллеги прежде, чем запросить/получить данные. javax.net.ssl.HttpsURLConnection расширяется java.net.HttpsURLConnection класс, и добавляет поддержку https-специфичных функций. См. java.net.URL, java.net.URLConnection, java.net.HttpURLConnection, и javax.net.ssl.HttpURLConnection классы для получения дополнительной информации о том, как https URL создаются и используются.

После получения a HttpsURLConnection, можно сконфигурировать много http/https параметров прежде фактически инициировать сетевое соединение через метод URLConnection.connect. Особенно интересный:

Установка Присвоенного SSLSocketFactory

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

HttpsURLConnection у класса есть значение по умолчанию SSLSocketFactory который присваивается, когда класс загружается. (В особенности это - фабрика, возвращенная методом SSLSocketFactory.getDefault.) Будущие экземпляры HttpsURLConnection наследует текущее значение по умолчанию SSLSocketFactory до нового значения по умолчанию SSLSocketFactory присваивается классу через статический метод HttpsURLConnection.setDefaultSSLSocketFactory. Однажды экземпляр HttpsURLConnection был создан, наследованный SSLSocketFactory на этом экземпляре может быть overriden со звонком setSSLSocketFactory метод.

Отметьте что, изменяя помехи по умолчанию SSLSocketFactory не имеет никакого эффекта на существующие экземпляры HttpsURLConnections, звонок setSSLSocketFactory метод необходим, чтобы изменить существующий экземпляр.

Можно получить на экземпляр или на класс SSLSocketFactory делая звонок getSSLSocketFactory/getDefaultSSLSocketFactory методы, соответственно.

Установка Присвоенного HostnameVerifier

Если имя хоста URL не соответствует имя хоста в учетных данных, полученных как часть квитирования SSL/TLS, возможно, что спуфинг URL произошел. Если реализация не может определить соответствие имени хоста с разумной уверенностью, реализация SSL выполнит обратный вызов к экземпляру, присвоился HostnameVerifier для проверки futher. Верификатор имени хоста может выполнить любые шаги, необходимы, чтобы сделать определение, такое как выполнение альтернативного сопоставления с образцом имени хоста или возможно появление интерактивное диалоговое окно. Неудачная проверка верификатором имени хоста закроет соединение. (См. RFC 2818 для получения дополнительной информации относительно проверки имени хоста.)

setHostnameVerifier/setDefaultHostnameVerifier методы работают подобным образом к setSSLSocketFactory/setDefaultSSLSocketFactory методы, в этом есть HostnameVerifiers присвоенный на основе на класс и на экземпляр, и текущей стоимости может быть получен звонком getHostnameVerifier/getDefaultHostnameVerifier методы.

Классы поддержки и Интерфейсы

Классы и интерфейсы в этом разделе обеспечиваются, чтобы поддерживать создание и инициализацию SSLContext объекты, которые используются, чтобы создать SSLSocketFactory, SSLServerSocketFactory, и SSLEngine объекты. Классы поддержки и интерфейсы являются частью javax.net.ssl пакет.

Три из классов, описанных в этом разделе ( SSLContext, KeyManagerFactory, и TrustManagerFactory) классы механизма. Класс механизма является классом API для определенных алгоритмов (или протоколы, в случае SSLContext), для которого реализации могут быть обеспечены в одном или Более провайдере криптографических служб (провайдер) пакеты. Для получения дополнительной информации по провайдерам и классам механизма, см. "Принципы разработки" и разделы "Понятий" Справочника Архитектуры Криптографии Java.

SunJSSE провайдер, который прибывает стандарт с JSSE, обеспечивает SSLContext, KeyManagerFactory, и TrustManagerFactory реализации, так же как реализации для классов механизма в стандартной безопасности Java (java.security) API. Реализации, предоставленные SunJSSE :

Класс механизма
Реализованный
Алгоритм или
Протокол
KeyStore PKCS12
KeyManagerFactory PKIX, SunX509
TrustManagerFactory PKIX (a.k.a. X509 или SunPKIX), SunX509
SSLContext SSLv3 (a.k.a. SSL), TLSv1 (a.k.a. TLS), TLSv1.1, TLSv1.2

SSLContext Класс

javax.net.ssl.SSLContext класс механизма для реализации протокола защищенного сокета. Экземпляр этого класса действует как фабрика для фабрик сокета SSL и механизмов SSL. SSLContext содержит всю информацию состояния, поделившуюся через все объекты, создаваемые под тем контекстом. Например, состояние сеанса связывается с SSLContext когда это согласовывается через протокол квитирования сокетами, создаваемыми фабриками сокета, обеспеченными контекстом. Эти кэшируемые сеансы могут быть снова использованы и совместно использованы другими сокетами, создаваемыми под тем же самым контекстом.

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

В настоящий момент только X.509-на-основе менеджеры поддерживаются.

Создание SSLContext Объект

Как другие основанные на провайдере классы "механизма" JCA, SSLContext объекты создаются, используя getInstance методы фабрики SSLContext класс. Эти статические методы каждый возврат экземпляр, который реализует, по крайней мере, требуемый протокол защищенного сокета. Возвращенный экземпляр может реализовать другие протоколы также. Например, getInstance("TLSv1") может возвратить экземпляр, который реализует "TLSv1", "TLSv1.1" и "TLSv1.2". getSupportedProtocols метод возвращает список поддерживаемых протоколов когда SSLSocket, SSLServerSocket или SSLEngine создается из этого контекста. Можно управлять, какие протоколы фактически включаются для соединения SSL при использовании метода setEnabledProtocols(String[] protocols).

Отметьте: SSLContext объект автоматически создается, инициализируется, и статически присваивается SSLSocketFactory класс, когда Вы вызываете SSLSocketFactory.getDefault. Поэтому, Вы не должны непосредственно создать и инициализировать SSLContext объект (если Вы не хотите переопределить поведение по умолчанию).

Создать SSLContext объект, вызывая a getInstance метод фабрики, следует определить имя протокола. Можно также определить, какой провайдер Вы хотите предоставить реализацию требуемого протокола:

public static SSLContext getInstance(String protocol);

public static SSLContext getInstance(String protocol,
                                     String provider);

public static SSLContext getInstance(String protocol,
                                     Provider provider);

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

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

Протокол является строкой (такой как "SSL"), который описывает требуемый протокол защищенного сокета. Общий протокол называет для SSLContext объекты определяются в Приложении A.

Вот пример получения SSLContext:

SSLContext sc = SSLContext.getInstance("SSL");

Недавно создаваемый SSLContext должен быть инициализирован, вызывая init метод:

public void init(KeyManager[] km, TrustManager[] tm,
                   SecureRandom random);

Если KeyManager[] парамать является нулем, затем пустое KeyManager будет определен для этого контекста. Если TrustManager[] параметр является нулем, установленные поставщики систем обеспечения безопасности будут искаться реализацию самого высокого приоритета TrustManagerFactory, от которого соответствующее TrustManager будет получен. Аналогично, параметр SecureRandom может быть нулем, когда реализация по умолчанию будет использоваться.

Если внутренний контекст по умолчанию используется, (например, a SSLContext создается SSLSocketFactory.getDefault() или SSLServerSocketFactory.getDefault()), значение по умолчанию KeyManager и a TrustManager создаются. Значение по умолчанию SecureRandom реализация также выбирается.

TrustManager Интерфейс

Основная ответственность TrustManager должен определить, нужно ли представленным учетным данным аутентификации доверять. Если учетным данным не будут доверять, то соединение будет завершено. Чтобы аутентифицировать удаленные идентификационные данные коллеги защищенного сокета, Вы должны инициализировать SSLContext объект с один или больше TrustManagers. Вы должны передать тот TrustManager для каждого механизма аутентификации, который поддерживается. Если нуль передают в SSLContext инициализация, доверительный менеджер будет создаваться для Вас. Как правило, есть единственный доверительный менеджер, который поддерживает аутентификацию, основанную на сертификатах с открытым ключом X.509 (например. X509TrustManager). Некоторые реализации защищенного сокета могут также поддерживать аутентификацию, основанную на совместно используемых секретных ключах, Kerberos, или других механизмах.

TrustManagers создаются любой a TrustManagerFactory, или обеспечивая конкретную реализацию интерфейса.

TrustManagerFactory Класс

javax.net.ssl.TrustManagerFactory класс механизма для основанной на провайдере службы, которая действует как фабрика для одного или более типов TrustManager объекты. Поскольку это основано на провайдере, дополнительные фабрики могут быть реализованы и сконфигурировали, которые предоставляют дополнительным или альтернативным доверительным менеджерам, которые предоставляют более сложные услуги или ту реализацию специфичные для установки политики аутентификации.

Создание a TrustManagerFactory

Вы создаете экземпляр этого класса подобным образом SSLContext, за исключением передачи алгоритма называют строку вместо имени протокола к getInstance метод:
public static TrustManagerFactory
                  getInstance(String algorithm);

public static TrustManagerFactory
                  getInstance(String algorithm,
                              String provider);

public static TrustManagerFactory
                  getInstance(String algorithm,
                              Provider provider);

Демонстрационная строка имени алгоритма:

"PKIX"

Демонстрационный вызов является следующим:

TrustManagerFactory tmf =
    TrustManagerFactory.getInstance("PKIX", "SunJSSE");

Вышеупомянутый вызов создаст экземпляр SunJSSE PKIX провайдера доверяют фабрике менеджера. Эта фабрика может тогда использоваться, чтобы создать доверительных менеджеров, которые обеспечивают PKIX-на-основе проверку законности пути сертификации X.509.

Инициализируя a SSLContext, можно использовать доверительных менеджеров, создаваемых из доверительной фабрики менеджера, или можно записать Вашему собственному доверительному менеджеру, возможно используя CertPath API. (См. Руководство Программиста API Пути Сертификации Java для деталей.) Вы не должны использовать доверительную фабрику менеджера вообще, если Вы реализуете доверительного менеджера, использующего X509TrustManager интерфейс.

Недавно создаваемая фабрика должна быть инициализирована, вызывая один из init методы:

public void init(KeyStore ks);
public void init(ManagerFactoryParameters spec);

Следует вызвать какой бы ни init метод является подходящим для TrustManagerFactory Вы используете. (Спросите поставщика провайдера.)

Для многих фабрик, таких как "SunX509" TrustManagerFactory от SunJSSE провайдер, KeyStore единственная информация, запрошенная, чтобы инициализировать TrustManagerFactory и таким образом первое init метод является соответствующим, чтобы вызвать. TrustManagerFactory запросит KeyStore для информации, на которой удаленным сертификатам нужно доверять во время проверок авторизации.

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

Например, предположите TrustManagerFactory провайдер требует параметров инициализации B, R, и S из любого приложения, которое хочет использовать того провайдера. Как все провайдеры, которые требуют параметров инициализации кроме KeyStore, провайдер потребует, чтобы приложение обеспечило экземпляр класса, который реализует деталь ManagerFactoryParameters подинтерфейс. В нашем примере предположите, что провайдер требует, чтобы вызывающее приложение реализовало и создало экземпляр MyTrustManagerFactoryParams и передайте это к второму init. Вот что MyTrustManagerFactoryParams может быть похожим:

public interface MyTrustManagerFactoryParams extends 
       ManagerFactoryParameters {
    public boolean getBValue();
    public float getRValue();
    public String getSValue():
}

Некоторые trustmanagers способны к принятию доверительных решений, не имея необходимость явно инициализироваться с объектом KeyStore или любыми другими параметрами. Например, они могут получить доступ к доверительному материалу от локальной службы каталогов через LDAP, могут использовать удаленный онлайновый сервер проверки состояния сертификата, или могут получить доступ к материалу доверия значения по умолчанию от стандартного локального расположения.

PKIX Поддержка TrustManager

Доверительный алгоритм менеджера по умолчанию является "PKIX". Значение по умолчанию может быть изменено, редактируя ssl.TrustManagerFactory.algorithm свойство в java.security файл.

PKIX полагают, что фабрика менеджера использует CertPath реализация PKIX от установленного поставщика систем обеспечения безопасности; "SUN" провайдер CertPath предоставляется Java Комплект разработчика 6 SE. Доверительная фабрика менеджера может быть инициализирована, используя нормальное init(KeyStore ks) метод, или передавая параметры CertPath к PKIX доверяет менеджеру, использующему недавно представленный класс javax.net.ssl.CertPathTrustManagerParameters.

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

import javax.net.ssl.*;
import java.security.cert.*;
import java.security.KeyStore;
...

// Create PKIX parameters
KeyStore anchors = KeyStore.getInstance("JKS");
anchors.load(new FileInputStream(anchorsFile));
CertPathParameters pkixParams = new PKIXBuilderParameters(anchors,
    new X509CertSelector());

// Specify LDAP certificate store to use
LDAPCertStoreParameters lcsp = new LDAPCertStoreParameters("ldap.imc.org", 389);
pkixParams.addCertStore(CertStore.getInstance("LDAP", lcsp));

// Specify that revocation checking is to be enabled
pkixParams.setRevocationEnabled(true);

// Wrap them as trust manager parameters
ManagerFactoryParameters trustParams =
    new CertPathTrustManagerParameters(pkixParams);

// Create TrustManagerFactory for PKIX-compliant trust managers
TrustManagerFactory factory = TrustManagerFactory.getInstance("PKIX");

// Pass parameters to factory to be passed to CertPath implementation
factory.init(trustParams);

// Use factory
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, factory.getTrustManagers(), null);

Если init(KeyStore ks) метод используется, PKIXParameters по умолчанию используются за исключением того, что проверка аннулирования отключается. Это может быть включено, устанавливая системное свойство com.sun.net.ssl.checkRevocation к true. Отметьте, что эта установка требует, чтобы реализация CertPath могла определить местоположение информации об аннулировании отдельно. Реализация PKIX в провайдере солнца может сделать это во многих случаях, но требует что системное свойство com.sun.security.enableCRLDP будьте установлены в true.

Больше информации о PKIX и API CertPath может быть найдено в Руководстве по Программированию API Пути Сертификата Java.

X509TrustManager Интерфейс

javax.net.ssl.X509TrustManager интерфейс расширяет генерала TrustManager интерфейс. Этот интерфейс должен быть реализован доверительным менеджером при использовании X.509-на-основе аутентификации.

Чтобы поддерживать аутентификацию X.509 удаленных коллег сокета через JSSE, экземпляр этого интерфейса нужно передать к init метод SSLContext объект.

Создание X509TrustManager

Можно или реализовать этот интерфейс непосредственно непосредственно или получить один из основанного на провайдере TrustManagerFactory (такие как предоставленное SunJSSE провайдер). Вы могли также реализовать свое собственное, которое делегирует сгенерированному фабрикой доверительному менеджеру. Например, Вы могли бы сделать это, чтобы фильтровать решения непреднамеренного траста и запросить конечного пользователя через графический интерфейс пользователя.

Отметьте: Если нулевой параметр KeyStore передают к SunJSSE "PKIX" или "SunX509" TrustManagerFactory, фабрика использует следующие шаги, чтобы попытаться найти доверительный материал:

  1. Если системное свойство:
    javax.net.ssl.trustStore
    
    определяется, тогда TrustManagerFactory попытки счесть файл, используя имя файла, определенное тем системным свойством, и использованием, что файлом для KeyStore. Если javax.net.ssl.trustStorePassword системное свойство также определяется, его значение используется, чтобы проверить целостность данных в базе доверенных сертификатов прежде, чем открыть его.

    Если javax.net.ssl.trustStore определяется, но указанный файл не существует, затем значение по умолчанию TrustManager использование пустого keystore создается.

  2. Если javax.net.ssl.trustStore системное свойство не было определено, затем если файл
    <java-home>/lib/security/jssecacerts
    
    существует, тот файл используется. (См. Каталог Установки <дом Java> для информации о какой <java-home> обращается к.) Иначе,
  3. Если файл
    <java-home>/lib/security/cacerts
    
    существует, тот файл используется.

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

Фабрика ищет файл, определенный через свойство безопасности javax.net.ssl.trustStore или для jssecacerts файл прежде, чем проверить на a cacerts файл так, чтобы можно было обеспечить JSSE-специфичный набор доверяемых корневых сертификатов, отдельных от, которые могли бы присутствовать в cacerts в целях подписывания кода.

Создание Вашего Собственного X509TrustManager

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

Следующий MyX509TrustManager класс улучшает значение по умолчанию SunJSSE X509 TrustManager поведение, обеспечивая альтернативную логику аутентификации, когда значение по умолчанию SunJSSE X509 TrustManager сбои.

class MyX509TrustManager implements X509TrustManager {

     /*
      * The default PKIX X509TrustManager9.  We'll delegate
      * decisions to it, and fall back to the logic in this class if the
      * default X509TrustManager doesn't trust it.
      */
     X509TrustManager pkixTrustManager;

     MyX509TrustManager() throws Exception {
         // create a "default" JSSE X509TrustManager.

         KeyStore ks = KeyStore.getInstance("JKS");
         ks.load(new FileInputStream("trustedCerts"),
             "passphrase".toCharArray());

         TrustManagerFactory tmf =
                TrustManagerFactory.getInstance("PKIX");
         tmf.init(ks);

         TrustManager tms [] = tmf.getTrustManagers();

         /*
          * Iterate over the returned trustmanagers, look
          * for an instance of X509TrustManager.  If found,
          * use that as our "default" trust manager.
          */
         for (int i = 0; i < tms.length; i++) {
             if (tms[i] instanceof X509TrustManager) {
                 pkixTrustManager = (X509TrustManager) tms[i];
                 return;
             }
         }

         /*
          * Find some other way to initialize, or else we have to fail the
          * constructor.
          */
         throw new Exception("Couldn't initialize");
     }

     /*
      * Delegate to the default trust manager.
      */
     public void checkClientTrusted(X509Certificate[] chain, String authType)
                 throws CertificateException {
         try {
             pkixTrustManager.checkClientTrusted(chain, authType);
         } catch (CertificateException excep) {
             // do any special handling here, or rethrow exception.
         }
     }

     /*
      * Delegate to the default trust manager.
      */
     public void checkServerTrusted(X509Certificate[] chain, String authType)
                 throws CertificateException {
         try {
             pkixTrustManager.checkServerTrusted(chain, authType);
         } catch (CertificateException excep) {
             /*
              * Possibly pop up a dialog box asking whether to trust the
              * cert chain.
              */
         }
     }

     /*
      * Merely pass this through.
      */
     public X509Certificate[] getAcceptedIssuers() {
         return pkixTrustManager.getAcceptedIssuers();
     }
}

Как только Вы создали такого доверительного менеджера, присвойте это SSLContext через init метод. Будущее SocketFactories создаваемый из этого SSLContext будет использовать Ваше новое TrustManager принимая доверительные решения.

TrustManager[] myTMs = new TrustManager [] {
                          new MyX509TrustManager() };
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, myTMs, null);

Обновление keyStore Динамически

Можно улучшить MyX509TrustManager обработать динамические обновления keystore. Когда a checkClientTrusted или checkServerTrusted протестируйте сбои и не устанавливайте доверяемую цепочку сертификата, можно добавить необходимый доверенный сертификат keystore. Вы должны создать новое pkixTrustManager от TrustManagerFactory инициализированный с обновленным keystore. Когда Вы устанавливаете новое соединение (использующий ранее инициализированный SSLContext), недавно добавленный сертификат будет использоваться, принимая доверительные решения.

X509ExtendedTrustManager Class

В Java SE 7 выпусков, X509ExtendedTrustManager класс является абстрактной реализацией X509TrustManager интерфейс. Это добавляет методы для чувствительного к соединению доверительного управления. Кроме того, это включает проверке конечной точки в уровне TLS.

В TLS 1.2 и позже, и клиент и сервер в состоянии определить, какой хеш и алгоритмы подписи они примут. Чтобы аутентифицировать удаленную сторону, решения аутентификации должны быть основаны и на сертификатах X509 и на локальном принятом хеше и алгоритмах подписи. Локальный принятый хеш и алгоритмы подписи могут быть получены от ExtendedSSLSession.getLocalSupportedSignatureAlgorithms() метод.

ExtendedSSLSession объект может быть получен, вызывая SSLSocket.getHandshakeSession() метод или SSLEngine.getHandshakeSession() метод.

X509TrustManager интерфейс не чувствителен к соединению. Это не обеспечивает способа получить доступ SSLSocket или SSLEngine свойства сеанса.

Помимо TLS 1.2 поддержки, X509ExtendedTrustManager класс также поддерживает ограничения алгоритма и проверку имени хоста уровня SSL. Для провайдеров JSSE и доверительных реализаций менеджера, X509ExtendedTrustManager класс настоятельно рекомендуется, а не наследство X509TrustManager интерфейс.

Создание X509ExtendedTrustManager

Можно или создать X509ExtendedTrustManager sublcass самостоятельно (который обрисовывается в общих чертах в следующем разделе) или получают один из основанного на провайдере TrustManagerFactory (такие как предоставленное SunJSSE провайдер). В Java SE 7 выпусков, PKIX или SunX509 TrustManagerFactory возвраты X509ExtendedTrustManager экземпляр.

Создание Вашего Собственного X509ExtendedTrustManager

Этот раздел обрисовывает в общих чертах, как разделить на подклассы X509ExtendedTrustManager почти тем же самым способом как описано для X509TrustManager.

Следующий класс использует "PKIX" TrustManagerFactory определять местоположение значения по умолчанию X509ExtendedTrustManager это будет использоваться, чтобы принять решения относительно доверия. Если доверительный менеджер по умолчанию перестал работать по какой-либо причине, подкласс в состоянии добавить другое поведение. В примере эти расположения обозначаются комментариями в catch пункты.

import java.io.*;
import java.net.*;

import java.security.*;
import java.security.cert.*;
import javax.net.ssl.*;

public class MyX509ExtendedTrustManager extends X509ExtendedTrustManager {

     /*
      * The default PKIX X509ExtendedTrustManager.  We'll delegate
      * decisions to it, and fall back to the logic in this class if the
      * default X509ExtendedTrustManager doesn't trust it.
      */
     X509ExtendedTrustManager pkixTrustManager;

     MyX509ExtendedTrustManager() throws Exception {
         // create a "default" JSSE X509ExtendedTrustManager.

         KeyStore ks = KeyStore.getInstance("JKS");
         ks.load(new FileInputStream("trustedCerts"),
             "passphrase".toCharArray());

         TrustManagerFactory tmf =
                TrustManagerFactory.getInstance("PKIX");
         tmf.init(ks);

         TrustManager tms [] = tmf.getTrustManagers();

         /*
          * Iterate over the returned trustmanagers, look
          * for an instance of X509TrustManager.  If found,
          * use that as our "default" trust manager.
          */
         for (int i = 0; i < tms.length; i++) {
             if (tms[i] instanceof X509ExtendedTrustManager) {
                 pkixTrustManager = (X509ExtendedTrustManager) tms[i];
                 return;
             }
         }

         /*
          * Find some other way to initialize, or else we have to fail the
          * constructor.
          */
         throw new Exception("Couldn't initialize");
     }

     /*
      * Delegate to the default trust manager.
      */
     public void checkClientTrusted(X509Certificate[] chain, String authType)
                 throws CertificateException {
         try {
             pkixTrustManager.checkClientTrusted(chain, authType);
         } catch (CertificateException excep) {
             // do any special handling here, or rethrow exception.
         }
     }

     /*
      * Delegate to the default trust manager.
      */
     public void checkServerTrusted(X509Certificate[] chain, String authType)
                 throws CertificateException {
         try {
             pkixTrustManager.checkServerTrusted(chain, authType);
         } catch (CertificateException excep) {
             /*
              * Possibly pop up a dialog box asking whether to trust the
              * cert chain.
              */
         }
     }

     /*
      * Connection-sensitive verification.
      */
     public void checkClientTrusted(X509Certificate[] chain, String authType,
                  Socket socket)
                 throws CertificateException {
       try {
           pkixTrustManager.checkClientTrusted(chain, authType, socket);
       } catch (CertificateException excep) {
           // do any special handling here, or rethrow exception.
       }
     }

     public void checkClientTrusted(X509Certificate[] chain, String authType,
                  SSLEngine engine)
                 throws CertificateException {
       try {
           pkixTrustManager.checkClientTrusted(chain, authType, engine);
       } catch (CertificateException excep) {
           // do any special handling here, or rethrow exception.
       }
     }

     public void checkServerTrusted(X509Certificate[] chain, String authType,
                  Socket socket)
                 throws CertificateException {
       try {
           pkixTrustManager.checkServerTrusted(chain, authType, socket);
       } catch (CertificateException excep) {
           // do any special handling here, or rethrow exception.
       }
     }

     public void checkServerTrusted(X509Certificate[] chain, String authType,
                  SSLEngine engine)
                 throws CertificateException {
       try {
           pkixTrustManager.checkServerTrusted(chain, authType, engine);
       } catch (CertificateException excep) {
           // do any special handling here, or rethrow exception.
       }
     }
     
     /*
      * Merely pass this through.
      */
     public X509Certificate[] getAcceptedIssuers() {
         return pkixTrustManager.getAcceptedIssuers();
     }
}

KeyManager Интерфейс

Основная ответственность KeyManager должен выбрать учетные данные аутентификации, которые будут в конечном счете отправлены удаленному узлу. Чтобы аутентифицировать себя (локальная коллега защищенного сокета) к удаленной коллеге, Вы должны инициализировать SSLContext объект с один или больше KeyManagers. Вы должны передать тот KeyManager для каждого различного механизма аутентификации, который будет поддерживаться. Если нуль передают в SSLContext инициализация, пустое KeyManager будет создаваться. Если внутренний контекст по умолчанию используется (например, a SSLContext создаваемый SSLSocketFactory.getDefault() или SSLServerSocketFactory.getDefault()), значение по умолчанию KeyManager создается. Как правило, есть единственный ключевой менеджер, который поддерживает аутентификацию, основанную на X.509 сертификаты с открытым ключом. Некоторые реализации защищенного сокета могут также поддерживать аутентификацию, основанную на совместно используемых секретных ключах, Kerberos, или других механизмах.

KeyManagers создаются любой a KeyManagerFactory, или обеспечивая конкретную реализацию интерфейса.

KeyManagerFactory Класс

javax.net.ssl.KeyManagerFactory класс механизма для основанной на провайдере службы, которая действует как фабрика для одного или более типов KeyManager объекты. SunJSSE провайдер реализует фабрику, которая может возвратить основного менеджера по ключу X.509. Поскольку это основано на провайдере, дополнительные фабрики могут быть реализованы и сконфигурированы, чтобы предоставить дополнительным или альтернативным ключевым менеджерам.

Создание a KeyManagerFactory

Вы создаете экземпляр этого класса подобным образом SSLContext, за исключением передачи алгоритма называют строку вместо имени протокола к getInstance метод:
public static KeyManagerFactory
                  getInstance(String algorithm);

public static KeyManagerFactory
                  getInstance(String algorithm,
                              String provider);

public static KeyManagerFactory
                  getInstance(String algorithm,
                              Provider provider);

Демонстрационная строка имени алгоритма:

"SunX509"

Демонстрационный вызов является следующим:

KeyManagerFactory kmf =
    KeyManagerFactory.getInstance("SunX509", "SunJSSE");

Вышеупомянутый вызов создаст экземпляр SunJSSE значение по умолчанию провайдера манипулирует фабрику менеджера, которая обеспечивает основные X.509-на-основе ключи аутентификации.

Недавно создаваемая фабрика должна быть инициализирована, вызывая один из init методы:

public void init(KeyStore ks, char[] password);
public void init(ManagerFactoryParameters spec);

Следует вызвать какой бы ни init метод является подходящим для KeyManagerFactory, который Вы используете. (Спросите поставщика провайдера.)

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

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

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

Как обозначено выше, SunJSSE провайдер поддерживает фабрику "SunX509", которая должна быть инициализирована с параметром KeyStore.

X509KeyManager Интерфейс

javax.net.ssl.X509KeyManager интерфейс расширяет генерала KeyManager интерфейс. Это должно быть реализовано ключевым менеджером по X.509-на-основе аутентификации. Чтобы поддерживать аутентификацию X.509, чтобы отдалить коллеги сокета через JSSE, экземпляр этого интерфейса нужно передать к init метод SSLContext объект.

Создание X509KeyManager

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

Создание Вашего Собственного X509KeyManager

Если значение по умолчанию X509KeyManager поведение не является подходящим для Вашей ситуации, можно создать свое собственное X509KeyManager в пути similiar к тому показанному в Создании Вашего Собственного X509TrustManager.

X509ExtendedKeyManager Класс

X509ExtendedKeyManager абстрактный класс является реализацией X509KeyManager интерфейс, который учитывает специфичный для соединения ключевой выбор. Это добавляет два метода, которые выбирают ключевой псевдоним для клиента или сервера, основанного на ключевом типе, разрешенном выпускающих, и ток SSLEngine.

public String chooseEngineClientAlias(String[] keyType,
                                      Principal[] issuers,
                                      SSLEngine engine)

public String chooseEngineServerAlias(String keyType,
                                      Principal[] issuers,
                                      SSLEngine engine)

Если ключевой менеджер не является экземпляром X509ExtendedKeyManager класс, это не будет работать с SSLEngine класс.

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

В TLS 1.2 и позже, и клиент и сервер в состоянии определить, какой хеш и алгоритмы подписи они примут. Чтобы передать аутентификацию, требуемую удаленной стороной, локальные ключевые решения выбора должны быть основаны и на сертификате X509 и на удаленном принятом хеше и алгоритмах подписи. Удаленный принятый хеш и алгоритмы подписи могут быть получены от метода ExtendedSSLSession.getPeerSupportedSignatureAlgorithms().

Можно создать свое собственное X509ExtendedKeyManager подкласс в пути, подобном показанному в Создании Вашего Собственного X509ExtendedTrustManager.

Отношения Между TrustManagers и KeyManagers

Исторически, был беспорядок относительно заданий TrustManagers и KeyManagers. В сводке вот основная ответственность каждого типа менеджера:
Ввести Функция
TrustManager Определяет, нужно ли удаленным учетным данным аутентификации (и таким образом соединение) доверять.
KeyManager Определяет который учетные данные аутентификации передаться к удаленному узлу.

Вторичные Классы Поддержки и Интерфейсы

Эти классы обеспечиваются как часть API JSSE, чтобы поддерживать создание, использовать, и управление защищенными сокетами. Они, менее вероятно, будут использоваться приложениями защищенного сокета, чем ядро и поддерживает классы. Вторичные классы поддержки и интерфейсы являются частью javax.net.ssl и javax.security.cert пакеты.

SSLParameters Класс

SSLParameters инкапсулирует вещи, которые влияют на соединение TLS:

Можно получить ток SSLParameters для SSLSocket или SSLEngine использование следующих методов:

Присвоиться SSLParameters с setSSLParameters() метод в SSLSocket, SSLServerSocket, или SSLEngine.

SSLSessionContext Интерфейс

A javax.net.ssl.SSLSessionContext группировка SSLSessions связанный с единственным объектом. Например, это могло быть связано с сервером или клиентом, который участвует во многих сеансах одновременно. Методы в этом интерфейсе включают перечислению всех сеансов в контексте и позволяют поиск определенных сеансов через их идентификаторы сеанса.

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

SSLSessionBindingListener Интерфейс

javax.net.ssl.SSLSessionBindingListener интерфейс, реализованный объектами, которые хотят быть уведомленными, когда они связываются или несвязанные от SSLSession.

SSLSessionBindingEvent Класс

A javax.net.ssl.SSLSessionBindingEvent событие, переданное к SSLSessionBindingListener когда это связывается или несвязанное от SSLSession.

HandShakeCompletedListener Интерфейс

javax.net.ssl.HandShakeCompletedListener интерфейс, реализованный любым классом, который хочет получить уведомление о завершении квитирования протокола SSL на данном SSLSocket соединение.

HandShakeCompletedEvent Класс

A javax.net.ssl.HandShakeCompletedEvent событие, переданное к a HandShakeCompletedListener после завершения SSL протокол квитируют на данном SSLSocket соединение.

HostnameVerifier Интерфейс

Если стандартная логика проверки имени хоста реализации SSL/TLS перестанет работать, то реализация вызовет verify метод класса, который реализует этот интерфейс и присваивается этому HttpsURLConnection экземпляр. Если класс обратного вызова может решить, что имя хоста приемлемо данный параметры, это должно сообщить, что соединение должно быть позволено. Недопустимый ответ заставит соединение быть завершенным.

Например:

public class MyHostnameVerifier implements HostnameVerifier {

    public boolean verify(String hostname, SSLSession session) {
        // pop up an interactive dialog box
        // or insert additional matching logic
        if (good_address) {
            return true;
        } else {
            return false;
        }
    }
}

//...deleted...

HttpsURLConnection urlc = (HttpsURLConnection)
  (new URL("https://www.sun.com/")).openConnection();
urlc.setHostnameVerifier(new MyHostnameVerifier());
См. HttpsURLConnection Класс для получения дополнительной информации о том, как присвоиться HostnameVerifier к HttpsURLConnection.

X509Certificate Класс

Много протоколов защищенного сокета выполняют аутентификацию, используя сертификаты с открытым ключом, также названные сертификатами X.509. Это - механизм аутентификации по умолчанию для протоколов TLS и SSL.

java.security.cert.X509Certificate абстрактный класс обеспечивает стандартный способ получить доступ к атрибутам сертификатов X.509.

Отметьте: javax.security.cert.X509Certificate класс поддерживается только для обратной совместимости с предыдущим (1.0.x и 1.1.x) версии JSSE. Новые приложения должны использовать java.security.cert.X509Certificate, нет javax.security.cert.X509Certificate.

AlgorithmConstraints Интерфейс

Java SE 7 выпусков включает интерфейс, java.security.AlgorithmConstraints, для того, чтобы управлять позволенный криптографические алгоритмы. AlgorithmConstraints определяет три permits() методы. Эти методы говорят, разрешаются ли имя алгоритма или ключ для определенных криптографических функций. Криптографические функции представляются рядом CryptoPrimitive, который является перечислением, содержащим поля как STREAM_CIPHER, MESSAGE_DIGEST, SIGNATURE, и больше.

Таким образом, AlgorithmConstraints реализация может ответить на вопросы как, "Я могу использовать этот ключ с этим алгоритмом с целью криптографической работы?"

AlgorithmConstraints объект может быть связан с SSLParameters объект используя новый метод, setAlgorithmConstraints(). Ток AlgorithmConstraints объект для SSLParameters объект получается с getAlgorithmConstraints().

Предыдущий (JSSE 1.0.x) Классы Реализации и Интерфейсы

В предыдущем (1.0.x) версии JSSE, была ссылочная реализация, классы которой и интерфейсы были обеспечены в com.sun.net.ssl пакет.

С v1.4 JSSE был интегрирован в J2SDK. Классы прежде в com.sun.net.ssl были продвинуты на javax.net.ssl пакет и является теперь частью стандартного API JSSE.

Поскольку совместимость имеет целью com.sun.net.ssl классы и интерфейсы все еще существуют, но были осуждены. Приложения, записанные, используя их, могут работать в J2SDK v1.4 и позже без того, чтобы быть перекомпилированным. Это может измениться в будущем выпуске; эти классы/интерфейсы могут быть удалены. Таким образом все новые приложения должны быть записаны, используя javax классы/интерфейсы.

Пока, приложения, записанные, используя com.sun.net.ssl API может использовать любого JSSE 1.0.2 провайдера (использование com.sun.net.ssl) или провайдеры JSSE, записанные для J2SDK v1.4 и позже (используя javax API). Однако, приложения, записанные, используя API JSSE в J2SDK 1.4 и позже, могут только использовать провайдеров JSSE, записанных для J2SDK 1.4 и позже. Там более свежие выпуски содержат некоторую новую функциональность и пытающийся получить доступ к такой функциональности на провайдере, который не предоставляет это, не работал бы. SunJSSE, если с JDK от Oracle, провайдер, записанный, используя javax API.

Можно все еще получить a com.sun.net.ssl.HttpsURLConnection если Вы обновляете путь поиска URL, устанавливая java.protocol.handler.pkgs System свойство, как Вы сделали при использовании JSSE 1.0.2. Для получения дополнительной информации см., что Код Использует HttpsURLConnection Класс... в разделе Поиска и устранения неисправностей.


Настройка JSSE

Каталог Установки <дом Java>

Термин <java-home> используется всюду по этому документу, чтобы сослаться на каталог, где Java SE 6 Сред выполнения (JRE) устанавливается. Это определяется основанное на том, выполняете ли Вы JSSE на JRE с или без установленного SDK Java. Java SE, 6 SDK включают JRE, но это располагается в различном уровне в файловой иерархии.

Следующее является некоторыми примерами который каталоги <java-home> обращается к:

Настройка

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

Некоторые из настроек делаются, устанавливая системное свойство или значения свойств безопасности. Разделы после таблицы объясняют, как установить такие значения свойств.


ВАЖНОЕ ПРИМЕЧАНИЕ: Многие из свойств, показанных в этой таблице, в настоящий момент используются реализацией JSSE, но нет никакой гарантии, что они будут продолжать иметь те же самые имена и типы (система или безопасность) или даже что они будут существовать вообще в будущих выпусках. Все такие свойства отмечаются с помощью "*". Они документируются здесь для Вашего удобства для использования с реализацией JSSE.
Настройка JSSE

Настраиваемый Элемент

Значение по умолчанию

Как Настроить

Реализация X509Certificate

Реализация X509Certificate от Oracle

Свойство безопасности cert.provider.x509v1

Реализация протокола HTTPS

Реализация от Oracle

Системное свойство java.protocol.handler.pkgs

реализация провайдера

SunJSSE

Строка security.provider.n= в файле свойств безопасности. См. описание.

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

Реализация SSLSocketFactory от Sun Microsystems.

** свойство безопасности ssl.SocketFactory.provider

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

Реализация SSLServerSocketFactory от Sun Microsystems.

** свойство безопасности ssl.ServerSocketFactory.provider

значение по умолчанию keystore

Никакое значение по умолчанию.

* системное свойство javax.net.ssl.keyStore
Отметьте что значение NONE может быть определен. Эта установка является соответствующей, если keystore не основан на файле (например, это находится в аппаратном маркере).

значение по умолчанию keystore пароль

Никакое значение по умолчанию.

* системное свойство javax.net.ssl.keyStorePassword

значение по умолчанию keystore провайдер

Никакое значение по умолчанию.

* системное свойство javax.net.ssl.keyStoreProvider

значение по умолчанию keystore тип

KeyStore.getDefaultType()

* системное свойство javax.net.ssl.keyStoreType

база доверенных сертификатов по умолчанию

jssecacerts, если это существует. Иначе, cacerts

* javax.net.ssl.trustStore системное свойство

пароль базы доверенных сертификатов по умолчанию

Никакое значение по умолчанию.

* системное свойство javax.net.ssl.trustStorePassword

провайдер базы доверенных сертификатов по умолчанию

Никакое значение по умолчанию.

* системное свойство javax.net.ssl.trustStoreProvider

тип базы доверенных сертификатов по умолчанию

KeyStore.getDefaultType()

* системное свойство javax.net.ssl.trustStoreType
Отметьте что значение NONE может быть определен. Эта установка является соответствующей, если база доверенных сертификатов не основана на файле (например, это находится в аппаратном маркере.)

ключевое имя алгоритма фабрики менеджера по умолчанию

SunX509

Свойство безопасности ssl.KeyManagerFactory.algorithm
доверительное имя алгоритма фабрики менеджера по умолчанию

PKIX

Свойство безопасности ssl.TrustManagerFactory.algorithm
отключенные криптографические алгоритмы проверки сертификата

MD2

Свойство безопасности jdk.certpath.disabledAlgorithms
отключенные криптографические алгоритмы комплекта шифра

Никакое значение по умолчанию.

Свойство безопасности jdk.tls.disabledAlgorithms
узел прокси по умолчанию

Никакое значение по умолчанию.

* системное свойство https.proxyHost
порт прокси по умолчанию

80

* системное свойство https.proxyPort
Опция Server Name Indication

true

* системное свойство jsse.enableSNIExtension. Индикация Имени сервера (SNI) является расширением TLS, определенным в RFC 4366. Это включает соединениям TLS с виртуальными серверами, в которых многократные серверы для различных сетевых имен размещаются в единственном базовом сетевом адресе.

Некоторые очень старые поставщики SSL/TLS, возможно, не в состоянии расширения SSL/TLS дескриптора. В этом случае установите это свойство в false отключить расширение SNI.
значение по умолчанию ciphersuites

Определенный фабрикой сокета.

* системное свойство https.cipherSuites. Это содержит список разделенных запятой значений имен комплекта шифра, определяющих который комплекты шифра включить для использования на этом HttpsURLConnection. См. SSLSocket setEnabledCipherSuites(String[]) метод.
протоколы квитирования значения по умолчанию

Определенный фабрикой сокета

* системное свойство https.protocols. Это содержит список разделенных запятой значений имен комплекта протокола, определяющих который комплекты протокола включить на этом HttpsURLConnection. См. метод SSLSocket setEnabledProtocols(String[]).
значение по умолчанию https порт

443

* Настраивают через port поле в https URL.
Алгоритмы шифрования JCE используются провайдером SunJSSE

Реализации SunJCE

Дайте альтернативному провайдеру (ам) алгоритма JCE более высокий привилегированный порядок чем провайдер SunJCE
измеряющие буферы по умолчанию для больших пакетов SSL/TLS

Никакое значение по умолчанию.

* системное свойство jsse.SSLEngine.acceptLargeFragments
Устанавливая это системное свойство в true, SSLSession измерит буферы, чтобы обработать большие пакеты данных по умолчанию. Это может заставить приложения выделять излишне большие буферы SSLEngine. Вместо этого приложения должны динамически проверить на условия переполнения буфера и изменить размеры буферов как соответствующих.

Позвольте Опасные Пересмотры SSL/TLS false * sun.security.ssl.allowUnsafeRenegotiation системное свойство.
Установка этого системного свойства к true разрешает полный (опасный) пересмотр наследства.
Позвольте Наследство, Привет обменивается сообщениями (Пересмотры) true * sun.security.ssl.allowLegacyHelloMessages системное свойство.
Установка этого системного свойства к true позволяет коллеге квитировать, не требуя надлежащих сообщений RFC 5746.

Свойство * This в настоящий момент используется реализацией JSSE. Это, как гарантируют, не будет исследоваться и использоваться другими реализациями. Если это исследуется другой реализацией, та реализация должна обработать это тем же самым способом, как реализация JSSE делает. Нет никакой гарантии, свойство будет продолжать существовать или иметь тот же самый тип (система или безопасность) в будущих выпусках.

Отметьте, что некоторые элементы настраиваются, устанавливая java.lang.System свойства, в то время как другие настраиваются, устанавливая java.security.Security свойства. Следующие разделы объясняют, как установить значения для обоих типов свойств.

Как Определить a java.lang.System Свойство

Некоторые аспекты JSSE могут быть настроены, устанавливая системные свойства. Есть несколько способов установить эти свойства:

Как Определить a java.security.Security Свойство

Некоторые аспекты JSSE могут быть настроены, устанавливая свойства безопасности. Можно установить свойство безопасности или статически или динамически:

Настройка Реализации X509Certificate

Реализация X509Certificate, возвращенная X509Certificate.getInstance метод является по умолчанию реализацией от реализации JSSE.

Можно дополнительно заставить различную реализацию быть возвращенной. Чтобы сделать так, определите имя (и пакет) класса альтернативной реализации как значение названного свойства безопасности cert.provider.x509v1. Например, если класс вызывают MyX509CertificateImpl и это появляется в com.cryptox пакет, следует поместить следующее в файл свойств безопасности:

cert.provider.x509v1=com.cryptox.MyX509CertificateImpl

Определение Альтернативной Реализации Протокола HTTPS

Можно связаться надежно с поддерживающим SSL веб-сервером при использовании "https" схемы URL java.net.URL класс. JDK обеспечивает значение по умолчанию https реализация URL.

Если Вы хотите, чтобы альтернатива https реализация протокола использовалась, установите java.protocol.handler.pkgs системное свойство, чтобы включать новое имя класса. Это действие заставляет указанные классы быть найденными и загруженными перед классами значения по умолчанию JDK. См. java.net.URL документация класса для деталей.

Отметьте предыдущим пользователям JSSE: В прошлом Sun выпуски JSSE необходимо установить java.protocol.handler.pkgs системное свойство во время установки JSSE. Этот шаг больше не требуется, если Вы не хотите получить экземпляр com.sun.net.ssl.HttpsURLConnection. Для получения дополнительной информации см., что Код Использует HttpsURLConnection Класс... в разделе Поиска и устранения неисправностей.

Настройка Реализации Провайдера

J2SDK 1.4 и более поздние выпуски прибывший стандарт с Провайдером криптографических служб JSSE, или провайдер, для краткости названный"SunJSSE". Провайдеры являются по существу пакетами, которые реализуют один или более классов механизма для определенных криптографических алгоритмов. Классы механизма JSSE SSLContext, KeyManagerFactory, и TrustManagerFactory. Для получения дополнительной информации по провайдерам и классам механизма, см. "Принципы разработки" и разделы "Понятий" Справочника Архитектуры Криптографии Java.

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

Регистрация Провайдера криптографических служб Статически

Вы регистрируете провайдера статически, добавляя строку следующей формы к файлу свойств безопасности:
security.provider.n=providerClassName

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

providerClassName является полностью определенным именем класса провайдера. Вы получаете это имя от поставщика провайдера.

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

Стандартный поставщик систем обеспечения безопасности и провайдер SunJSSE, поставленный с Java SE 6 платформ, автоматически регистрируются для Вас; следующие строки появляются в java.security файл свойств безопасности, чтобы зарегистрировать поставщика систем обеспечения безопасности SunJCE в привилегированном порядке 5 и провайдера SunJSSE с привилегированным порядком 4:

          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

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

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

Регистрация Провайдера криптографических служб Динамически

Вместо того, чтобы регистрировать провайдера статически, можно добавить провайдера динамически во время выполнения, вызывая Security.addProvider метод в начале Вашей программы. Например, чтобы динамически добавить провайдера, имя класса Провайдера которого MyProvider и чей MyProvider класс находится в com.ABC пакет, Вы вызвали бы:

Security.addProvider(
  new com.ABC.MyProvider());

Security.addProvider метод добавляет указанного провайдера к следующей доступной привилегированной позиции.

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

Настройка Баз ключей По умолчанию и Баз доверенных сертификатов, Типов Хранилища, и Паролей Хранилища

Всякий раз, когда значение по умолчанию SSLSocketFactory или SSLServerSocketFactory создается (через звонок SSLSocketFactory.getDefault или SSLServerSocketFactory.getDefault), и это значение по умолчанию SSLSocketFactory (или SSLServerSocketFactory) прибывает из ссылочной реализации JSSE, значения по умолчанию SSLContext связывается с фабрикой сокета. (Фабрика сокета по умолчанию прибудет из реализации JSSE.)

Это значение по умолчанию SSLContext инициализируется со значением по умолчанию KeyManager и a TrustManager. Если keystore определяется javax.net.ssl.keyStore системное свойство и соответствующее javax.net.ssl.keyStorePassword системное свойство, тогда KeyManager создаваемый значением по умолчанию SSLContext будет a KeyManager реализация для того, чтобы управлять указанным keystore. (Фактическая реализация будет как определена в Настройке Ключевых и Доверительных менеджеров По умолчанию.), Если никакое такое системное свойство не определяется, то keystore, которым управляют KeyManager будет новый пустой keystore.

Обычно, коллега, действующая как сервер в квитировании, будет нуждаться в keystore для своего KeyManager, чтобы получить учетные данные для аутентификации клиенту. Однако, если один из анонимных комплектов шифра выбирается, сервер KeyManager keystore не необходим. И, если сервер не требует аутентификации клиента, коллега, действующая, поскольку клиент не будет нуждаться в a KeyManager keystore. Таким образом в этих ситуациях это может быть хорошо, если есть нет javax.net.ssl.keyStore системное значение свойства определяется.

Точно так же, если база доверенных сертификатов определяется javax.net.ssl.trustStore системное свойство, тогда TrustManager создаваемый значением по умолчанию SSLContext будет a TrustManager реализация для того, чтобы управлять указанной базой доверенных сертификатов. В этом случае, если такое свойство существует, но файл, который оно определяет, не делает, тогда никакая база доверенных сертификатов не используется. Если нет javax.net.ssl.trustStore свойство существует, затем база доверенных сертификатов по умолчанию разыскивается. Если базу доверенных сертификатов называют <java-home>/lib/security/jssecacerts находится, это используется. В противном случае тогда базу доверенных сертификатов называют <java-home>/lib/security/cacerts разыскивается и используется (если это существует). См. Каталог Установки <дом Java> для информации относительно какой <java-home> обращается к. Наконец, если база доверенных сертификатов все еще не находится, то база доверенных сертификатов, которой управляют TrustManager будет новая пустая база доверенных сертификатов.


ВАЖНОЕ ПРИМЕЧАНИЕ: JDK поставляет с ограниченным количеством доверяемых корневых сертификатов в <java-home>/lib/security/cacerts файл. Как задокументировано в keytool, это - Ваша обязанность поддержать (то есть, добавьте/удалите), сертификаты, содержавшиеся в этом файле, если Вы используете этот файл в качестве базы доверенных сертификатов.

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


Если системные свойства javax.net.ssl.keyStoreType и/или javax.net.ssl.keyStorePassword также определяются, они обрабатываются как значение по умолчанию KeyManager тип keystore и пароль, соответственно. Если нет никакого определенного типа, тип по умолчанию то, что возвращен KeyStore.getDefaultType(), который является значением keystore.type свойство безопасности, или "jks", если никакое такое свойство безопасности не определяется. Если нет никакого keystore определенного пароля, это, как предполагается, "".

Точно так же, если системные свойства javax.net.ssl.trustStoreType и/или javax.net.ssl.trustStorePassword также определяются, они обрабатываются как тип базы доверенных сертификатов по умолчанию и пароль, соответственно. Если нет никакого определенного типа, тип по умолчанию то, что возвращен KeyStore.getDefaultType(). Если нет никакого определенного пароля базы доверенных сертификатов, это, как предполагается, "".

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

Настройка Ключевых и Доверительных менеджеров По умолчанию

Как отмечено в Настройке Баз ключей По умолчанию и Баз доверенных сертификатов, Типов Хранилища, и Паролей Хранилища, всякий раз, когда значение по умолчанию SSLSocketFactory или SSLServerSocketFactory создается, и это значение по умолчанию SSLSocketFactory (или SSLServerSocketFactory) прибывает из ссылочной реализации JSSE, значения по умолчанию SSLContext связывается с фабрикой сокета.

Это значение по умолчанию SSLContext инициализируется с a KeyManager и a TrustManager. KeyManager и/или TrustManager предоставленный значению по умолчанию SSLContext будет a KeyManager/TrustManager реализация для того, чтобы управлять указанным keystore/truststore, как описано в вышеупомянутом разделе.

KeyManager выбранная реализация определяется первым исследованием

ssl.KeyManagerFactory.algorithm
свойство безопасности. Если такое значение свойства определяется, a KeyManagerFactory реализация для указанного алгоритма разыскивается. Реализация от первого провайдера, который предоставляет реализацию, используется. getKeyManagers метод вызывают, чтобы определить KeyManager предоставлять к значению по умолчанию SSLContext. (Технически, getKeyManagers возвращает массив KeyManagers, один KeyManager для каждого типа ключевого материала.), Если нет такого определенного значения свойства безопасности, значение по умолчанию "SunX509" используется, чтобы выполнить поиск. Отметьте: A KeyManagerFactory реализация для алгоритма "SunX509" предоставляется SunJSSE провайдер. KeyManager это определяет, a javax.net.ssl.X509KeyManager реализация.

Точно так же TrustManager выбранная реализация определяется первым исследованием

ssl.TrustManagerFactory.algorithm
свойство безопасности. Если такое значение свойства определяется, a TrustManagerFactory реализация для указанного алгоритма разыскивается. Реализация от первого провайдера, который предоставляет реализацию, используется. getTrustManagers метод вызывают, чтобы определить TrustManager предоставлять к значению по умолчанию SSLContext. (Технически, getTrustManagers возвращает массив TrustManagers, один TrustManager для каждого типа доверительного материала.), Если нет такого определенного значения свойства безопасности, значение по умолчанию "PKIX" используется, чтобы выполнить поиск. Отметьте: A TrustManagerFactory реализация для алгоритма "PKIX" предоставляется SunJSSE провайдер. TrustManager это определяет, a javax.net.ssl.X509TrustManager реализация.

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

Отключенные Криптографические алгоритмы

Криптографический хеш-алгоритм MD2 больше не считают безопасным. SE Java 7 выпусков включают два новых свойства безопасности и новый API, которые поддерживают отключающие определенные криптографические алгоритмы.

jdk.tls.disabledAlgorithms свойство применяется к квитированию TLS, в то время как jdk.certpath.disabledAlgorithms свойство применяется к обработке пути сертификации.

Например, значение по умолчанию jdk.certpath.disabledAlgorithms MD2. Это означает, что любой сертификат, подписанный с MD2, не является приемлемым.

Каждое свойство безопасности содержит список криптографических алгоритмов, которые не будут использоваться во время обработки пути сертификации. Точный синтаксис свойств описывается в jre/lib/security/java.security файл, но кратко получается в итоге здесь.

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

Например, следующая строка в java.security определяет, что MD2 и алгоритмы DSA не должны использоваться для обработки пути сертификации. Кроме того RSA отключается для размеров ключа меньше чем 2048 битов.

jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048

Настройка Провайдеров Алгоритма шифрования

С Java SE 5 выпусков провайдер SunJSSE использует реализацию SunJCE для всех своих криптографических потребностей. В то время как рекомендуется, чтобы Вы оставили провайдера Sun в его регулярной позиции, можно использовать реализации от других провайдеров JCA/JCE, регистрируя их перед провайдером SunJCE. Стандартный механизм JCA может использоваться, чтобы сконфигурировать провайдеров, любой статически через файл свойств безопасности

<java-home>/lib/security/java.security
или динамически через addProvider или insertProviderAt метод в java.security.Security класс. (См. Каталог Установки <дом Java> для информации о какой <java-home> обращается к.)

Отметьте Людьми, Реализующими Провайдеров

Строки преобразования, используемые, когда SunJSSE вызывает Cipher.getInstance() "RSA/ECB/PKCS1Padding", "RC4", "DES/CBC/NoPadding", и "DESede/CBC/NoPadding". Поскольку дополнительная информация о классе Шифра и строках преобразования видит Спецификацию Криптографии.

Безопасность Транспортного уровня (TLS) Проблема Пересмотра

Введение

В Падении 2009 дефект был обнаружен в протоколах SSL/TLS. Фиксация к протоколу была разработана Рабочей группой TLS IETF, и текущие версии JDK содержат эту фиксацию. Этот раздел описывает ситуацию в намного большем количестве деталей, наряду с проблемами функциональной совместимости, связываясь с более старыми реализациями, чтобы не содержать этот протокол, фиксируют.

Уязвимость, учтенная, Человек В Середине (MITM) вводит атаки, где выбранный простой текст мог быть введен как префикс к соединению TLS. Эта уязвимость не позволяет атакующему дешифровать или изменять прерванные сетевые коммуникации, как только клиент и сервер успешно согласовал сеанс между собой. Эта уязвимость была раскрыта в:

и дополнительная информация доступна в:

Поэтапный Подход К Устранению Этой Проблемы

Фиксация для этой проблемы была обработана в двух фазах:

Семейство JDK Уязвимый
Выпуски
Фаза 1 Фиксирует
(Отключение Reneg.)
Фаза 2 Фиксирует
(RFC 5746)
JDK и JRE 6 Обновите 18 и ранее Обновления 19-21 Обновление 22
JDK и JRE 5.0 Обновите 23 и ранее Обновления 24-25 Обновление 26
SDK и JRE 1.4.2 Обновите 25 и ранее Обновления 26-27 Обновление 28

ОТМЕТЬТЕ: В конфигурации значения по умолчанию Фазы 2 нет никакого воздействия к приложениям, которые не требуют пересмотров. Приложения, которые требуют пересмотра (например, веб-серверы, которые первоначально позволяют анонимный клиент просматривать, но позже требуют SSL/TLS аутентифицируемые клиенты):

Описание Фазы 2 Фиксирует

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

С Фазой 2 фиксируют, у SunJSSE теперь есть три "режима функциональной совместимости пересмотра." Каждый режим полностью поддерживает безопасный пересмотр 5746 RFC, но имеет, они добавили семантику, связываясь с необновленной коллегой:

  1. Строгий режим: Требует, чтобы и клиент и сервер был обновлен до RFC 5746 и отправил надлежащие сообщения RFC 5746. В противном случае начальная буква (или последующий) квитирование перестанет работать, и соединение будет завершено.

  2. Взаимодействующий режим (значение по умолчанию): Использование надлежащих сообщений RFC 5746 является дополнительным, однако наследство (исходные спецификации SSL/TLS), пересмотры отключаются, если надлежащие сообщения не используются. Начальные соединения наследства все еще позволяются, но пересмотры наследства отключаются. Это - лучшее соединение безопасности и функциональной совместимости, и является настройкой по умолчанию.

  3. Небезопасный режим: Разрешает полный пересмотр наследства. Наиболее взаимодействующий с коллегами наследства, но уязвимый для исходной атаки MITM.

Различия режима выше только влияют на соединение с необновленной коллегой. Идеально, строгий (полный RFC 5746) режим должен использоваться для всех клиентов/серверов, однако это займет время для всех развернутых реализаций SSL/TLS, чтобы поддерживать RFC 5746, таким образом взаимодействующий режим будет значением по умолчанию пока.

Вот некоторая дополнительная информация о функциональной совместимости:

Клиент Сервер Режим
Обновленный Обновленный Безопасный Пересмотр во всех режимах.
Наследство [1] Обновленный
  • Строгий: Если клиенты не отправят надлежащие сообщения RFC 5746, то начальные соединения будут сразу завершены сервером (SSLHandshakeException/handshake_failure).
  • Взаимодействующий: Начальные соединения от клиентов наследства позволили (недостающие сообщения RFC 5746), но пересмотры не будут позволены сервером. [2] [3]
  • Небезопасный: Соединения и пересмотры с клиентами наследства позволяются, но уязвимы для исходной атаки MITM.
Обновленный Наследство [1]
  • Строгий: Если сервер не ответит надлежащими сообщениями RFC 5746, то клиент сразу завершит соединение (SSLHandshakeException/handshake_failure).
  • Взаимодействующий: клиент не будет требовать надлежащего начального сообщения RFC 5746 от сервера, но пересмотры не будут позволены клиентом. [2] [3]
  • Небезопасный: Соединения и пересмотры с клиентами наследства позволяются, но уязвимы для исходной атаки MITM.
Наследство [1] Наследство [1] Существующее поведение SSL/TLS, уязвимое для атаки MITM.

[1] Наследство означает исходные спецификации SSL/TLS (то есть не-RFC 5746).

[2] Реализации Фазы 1 SunJSSE (см. выше), пересмотры отклонения если определенно не повторно включено. Если пересмотры будут повторно включены, то они будут обработаны как Наследство RFC 5746-совместимая коллега, так как они не отправляют надлежащие сообщения RFC 5746.

[3] На SSL/TLS пересмотры могут инициироваться любой стороной. Как Фаза 1 фиксируют, приложения, связывающиеся с необновленной коллегой во Взаимодействующем режиме и той попытке инициировать пересмотр (через SSLSocket.startHandshake() или SSLEngine.beginHandshake()) получит a SSLHandshakeException (IOException) и соединение будет завершением работы (handshake_failure). Приложения, которые получают запрос пересмотра от необновленной коллеги, ответят согласно типу соединения на месте:

Чтобы установить эти режимы, два системных свойства используются:

режим allowLegacyHelloMessages allowUnsafeRenegotiation
Строгий ложь ложь
Взаимодействующий (значение по умолчанию) истина ложь
Небезопасный истина истина

ПРЕДУПРЕЖДЕНИЕ: не рекомендуется повторно включить небезопасному пересмотру SSL/TLS, поскольку уязвимость еще раз присутствует.

Для получения информации о том, как сконфигурировать определенный режим, устанавливая системное свойство, см., Как Определить a java.lang.System Свойство.

Обходные решения/Альтернативы к Пересмотру SSL/TLS

Все коллеги должны быть обновлены к RFC 5746-совместимая реализация как можно скорее. Даже с этим RFC 5746 фиксируют, на связь с необновленными коллегами будут воздействовать, если пересмотр будет необходим. Вот несколько предложенных опций:

\

Детали реализации

RFC 5746 определяет две новых структуры данных, которые упоминаются здесь для усовершенствованных пользователей:

Любой из них может использоваться, чтобы сигнализировать, что реализация является 5746-совместимым RFC и может выполнить безопасные пересмотры. Пожалуйста, см. обсуждение электронной почты IETF с ноября 2009 до февраля 2010 для соответствующих технических обсуждений.

RFC 5746 учитывает клиенты, чтобы отправить или SCSV или RI в первом ClientHello. Для максимальной функциональной совместимости SunJSSE будет использовать SCSV по умолчанию как некоторые, TLS и серверы SSL не обрабатывают неизвестные расширения правильно. Присутствие SCSV во включенных Комплектах Шифра (то есть. SSLSocket.setEnabledCipherSuites()/SSLEngine.setEnabledCipherSuites() определит, отправляется ли SCSV в начальном ClientHello, или если RI должен быть отправлен вместо этого.

SSLv2 не поддерживает расширения SSL/TLS. Если SSLv2Hello протокол включается, SCSV будет отправлен в начальном ClientHello.

Описание Фазы 1 Фиксирует

Как упомянуто выше, Фиксация Фазы 1 должна была отключить пересмотры по умолчанию до RFC, 5746-совместимая фиксация могла быть разработана. Пересмотры могли быть повторно включены, устанавливая sun.security.ssl.allowUnsafeRenegotiation системное свойство. Фаза 2 фиксирует использование то же самое системное свойство с добавлением sun.security.ssl.allowUnsafeRenegotiation системное свойство, чтобы потребовать использования сообщений RFC 5746.

Все приложения должны обновить до Фазы 2 RFC 5746, фиксируют как можно скорее.

JCE и Аппаратные средства Поддержка Acceleration/Smartcard

Использование JCE

Расширение Криптографии Java (JCE) является рядом пакетов, который служит основой и реализациями для шифрования, генерацией ключей и согласованием ключей, и Кодом аутентификации сообщений (MAC) алгоритмы. До Java SE 5, провайдер SunJSSE мог использовать провайдеров JCE когда конфигурирующийся, чтобы сделать так, но это все еще содержало внутренний криптографический код, который не использовал JCE. В Java SE 6, провайдер SunJSSE использует JCE исключительно для всех его криптографических операций и следовательно, в состоянии автоматически использовать в своих интересах функции JCE и улучшения, включая недавно добавленную поддержку JCE PKCS#11. Это позволяет провайдеру SunJSSE в Java SE 6 быть в состоянии использовать аппаратные средства криптографические акселераторы для существенных улучшений производительности и использовать Smartcards в качестве keystores для большей гибкости в ключевом и доверительном управлении.

Аппаратные Акселераторы

Использование аппаратных средств, криптографические акселераторы являются автоматическими, если JCE был сконфигурирован, чтобы использовать провайдера Oracle PKCS#11, который поочередно был сконфигурирован, чтобы использовать базовые аппаратные средства акселератора. Провайдер должен быть сконфигурирован перед любыми другими провайдерами JCE/JCA в списке провайдера. См. PKCS#11 Руководство для деталей о том, как сконфигурировать провайдера Oracle PKCS#11.

Конфигурирование JSSE, чтобы использовать Smartcards в качестве Keystores и Trust Stores

Поддержка в JCE для PKCS#11 также включает доступу к Smartcards как keystore. См. раздел Настройки для деталей о том, как сконфигурировать тип и расположение keystores, который будет использоваться JSSE. Чтобы использовать Smartcard в качестве keystore или базы доверенных сертификатов, установите javax.net.ssl.keyStoreType и системные свойства javax.net.ssl.trustStoreType, соответственно, к "pkcs11", и установите javax.net.ssl.keyStore и системные свойства javax.net.ssl.trustStore, соответственно, к NONE. Чтобы определить использование определенного провайдера, используйте javax.net.ssl.keyStoreProvider и системные свойства javax.net.ssl.trustStoreProvider (например, "SunPKCS11-joe"). При использовании этих свойств можно сконфигурировать приложение, которое ранее зависело от этих свойств, чтобы получить доступ к основанному на файле keystore, чтобы использовать Smartcard keystore без изменений к приложению.

Некоторые приложения запрашивают использование keystores программно. Эти приложения могут продолжать использовать существующие API, чтобы инстанцировать Keystore и передать его его ключевому менеджеру и доверять менеджеру. Если экземпляр Keystore обратится к PKCS#11 keystore поддержанный Smartcard, то у приложения JSSE будет доступ к ключам на Smartcard.

Многократный и Динамический Keystores

У Smartcards (и другие съемные маркеры) есть дополнительные требования для X509KeyManager. Различный Smartcards может присутствовать в читателе Smartcard во время времени жизни приложения Java, и они могут защищенные использующие различные пароли. pre-J2SE 5 API и менеджер по ключу SunX509 не размещают эти требования хорошо. В результате в Java SE 5, новые API были представлены, и новая реализация X509KeyManager была добавлена к провайдеру SunJSSE.

Класс java.security.KeyStore.Builder абстрагирует конструкцию и инициализацию объекта KeyStore. Это поддерживает использование CallbackHandlers для запроса пароля и может быть разделено на подклассы, чтобы поддерживать дополнительные функции как требующийся приложением. Например, возможно реализовать Разработчика, который позволяет записям человека Кеистора быть защищенными с различными паролями. Класс javax.net.ssl.KeyStoreBuilderParameters тогда может использоваться, чтобы инициализировать KeyManagerFactory, используя один или больше этих объектов Разработчика.

Новая реализация X509KeyManager в провайдере SunJSSE по имени "NewSunX509" поддерживает эти параметры. Если многократные сертификаты доступны, это также прилагает усилие, чтобы выбрать сертификат с соответствующим ключевым использованием и предпочитает допустимый сертификатам с истекшим сроком

Вот пример того, как сказать JSSE использовать обоих PKCS#11 keystore (который мог бы поочередно использовать Smartcard), и PKCS#12 основанный на файле keystore.

import javax.net.ssl.*;
import java.security.KeyStore.*;
...

// Specify keystore builder parameters for PKCS#11 keystores
Builder scBuilder = Builder.newInstance("PKCS11", null,
    new CallbackHandlerProtection(myGuiCallbackHandler));

// Specify keystore builder parameters for a specific PKCS#12 keystore
Builder fsBuilder = Builder.newInstance("PKCS12", null,
    new File(pkcsFileName), new PasswordProtection(pkcsKsPassword));

// Wrap them as key manager parameters
ManagerFactoryParameters ksParams =
    new KeyStoreBuilderParameters(
        Arrays.asList(new Builder[] { scBuilder, fsBuilder }));

// Create KeyManagerFactory
KeyManagerFactory factory = KeyManagerFactory.getInstance("NewSunX509");

// Pass builder parameters to factory
factory.init(ksParams);

// Use factory
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(factory.getKeyManagers(), null, null);

Комплекты Шифра Kerberos

В Java SE 6, у провайдера SunJSSE есть поддержка комплектов шифра Kerberos, как описано в RFC 2712. Следующие комплекты шифра поддерживаются, но не включаются по умолчанию.
TLS_KRB5_WITH_RC4_128_SHA
TLS_KRB5_WITH_RC4_128_MD5
TLS_KRB5_WITH_3DES_EDE_CBC_SHA
TLS_KRB5_WITH_3DES_EDE_CBC_MD5
TLS_KRB5_WITH_DES_CBC_SHA
TLS_KRB5_WITH_DES_CBC_MD5
TLS_KRB5_EXPORT_WITH_RC4_40_SHA
TLS_KRB5_EXPORT_WITH_RC4_40_MD5
TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA
TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5
Чтобы включить использованию этих комплектов шифра, следует сделать так явно. См. SSLEngine.setEnabledCipherSuites() и SSLSocket.setEnabledCipherSuites() для получения дополнительной информации. Как со всеми другими комплектами шифра SSL/TLS, если комплект шифра не будет поддерживаться коллегой, то это не будет выбрано во время согласования шифра. Кроме того, если приложение и/или сервер не могут получить необходимые учетные данные Kerberos, то комплекты шифра Kerberos также не будут выбраны.

Вот пример клиента TLS, который хочет использовать только комплект шифра TLS_KRB5_WITH_DES_CBC_SHA.

// Create socket
SSLSocketFactory sslsf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslSocket = (SSLSocket) sslsf.createSocket(tlsServer, serverPort);

// Enable only one cipher suite
String enabledSuites[] = { "TLS_KRB5_WITH_DES_CBC_SHA" };
sslSocket.setEnabledCipherSuites(enabledSuites);

Требования Kerberos

Следует установить инфраструктуру Kerberos в Вашей среде развертывания прежде, чем можно будет использовать комплекты шифра Kerberos с JSSE. В частности у обоих клиент и сервер TLS должны быть учетные записи, установленные с Центром распределения ключей Kerberos (KDC). Во время выполнения, если один или больше комплектов шифра Kerberos были включены, клиент и сервер TLS получит их учетные данные Kerberos, связанные с их соответствующей учетной записью от KDC. Например, сервер TLS, работающий на машине mach1.imc.org в области Kerberos IMC.ORG, должен иметь учетную запись с именем host/mach1.imc.org@IMC.ORG и быть сконфигурирован, чтобы использовать KDC для IMC.ORG. См. документ Требований Kerberos для информации об использовании Kerberos с Java SE.

Приложение может получить свои учетные данные Kerberos при использовании Службы Аутентификации и авторизации Java (JAAS) и модуля входа в систему Kerberos. Java Комплект разработчика 6 SE идет с модулем входа в систему Kerberos. Можно использовать комплекты шифра Kerberos с JSSE с, или без программирования JAAS, подобного тому, как можно использовать Java Универсальные Службы безопасности (Java GSS) с, или без программирования JAAS.

Чтобы использовать это без программирования JAAS, следует использовать имена индексов "com.sun.net.ssl.server" или "other" для сервера TLS запись конфигурации JAAS и "com.sun.net.ssl.client" или "other" для клиента TLS, и установить системное свойство javax.security.auth.useSubjectCredsOnly в ложь. Например, у сервера TLS, который не использует программирование JAAS, мог бы быть следующий конфигурационный файл JAAS.

com.sun.net.ssl.server {
  com.sun.security.auth.module.Krb5LoginModule required
        principal="host/mach1.imc.org@IMC.ORG"
        useKeyTab=true
        keyTab=mach1.keytab
        storeKey=true;
};
Пример того, как к Java GSS и Kerberos без программирования JAAS описываются в Java Учебное руководство GSS. Можно адаптировать это, чтобы использовать JSSE, заменяя Java, который GSS вызывает с вызовами JSSE.

Чтобы использовать комплекты шифра Kerberos с программированием JAAS, можно использовать любое имя индекса, потому что Ваше приложение ответственно за создание LoginContext JAAS, используя имя индекса, и затем обертывая вызовы JSSE в вызове Subject.doAsPrivileged() или Subject.doAs(). Пример того, как использовать JAAS с Java GSS и Kerberos, описывается в Java Учебное руководство GSS. Можно адаптировать это, чтобы использовать JSSE, заменяя Java, который GSS вызывает с вызовами JSSE.

Если Вы испытываете затруднения, используя или конфигурируя приложение JSSE, чтобы использовать Kerberos, см. раздел Поиска и устранения неисправностей Java Учебное руководство GSS.

Равноправная информация об Идентификационных данных

Чтобы определить идентификационные данные коллеги соединения SSL, используйте метод getPeerPrincipal() в следующих классах: javax.net.ssl.SSLSession, javax.net.ssl.HttpsURLConnection, и javax.net.HandshakeCompletedEvent. Точно так же, чтобы получить идентификационные данные, которые были отправлены коллеге (чтобы идентифицировать локальный объект), используйте getLocalPrincipal() в этих классах. Для X509-на-основе комплектов шифра эти методы возвратят экземпляр javax.security.auth.x500.X500Principal; для комплектов шифра Kerberos эти методы возвратят экземпляр javax.security.auth.kerberos.KerberosPrincipal.

До Java SE 5, приложения JSSE используемый getPeerCertificates() и подобные методы в javax.net.ssl.SSLSession, javax.net.ssl.HttpsURLConnection, и javax.net.HandshakeCompletedEvent, чтобы получить информацию о коллеге. Когда у коллеги нет никаких сертификатов, SSLPeerUnverifiedException бросается. Поведение этих методов остается неизменным в Java SE 6, что означает, что, если соединение было защищено, используя комплект шифра Kerberos, эти методы бросят SSLPeerUnverifiedException.

Если приложение должно определить только идентификационные данные коллеги или идентификационные данные, отправленные коллеге, это должно использовать методы getPeerPrincipal() И getLocalPrincipal(), соответственно. Это должно использовать getPeerCertificates() и getLocalCertificates(), только если это должно исследовать содержание тех сертификатов. Кроме того это должно быть подготовлено обработать случай, где у аутентифицируемой коллеги не могло бы быть никакого сертификата.

Менеджер безопасности

Когда менеджер безопасности был включен, в дополнение к SocketPermission s должен был связаться с коллегой, клиентское приложение TLS, которое использует комплекты шифра Kerberos также, нуждается в следующем разрешении.
javax.security.auth.kerberos.ServicePermission(serverPrincipal, "initiate");
где serverPrincipal является именем принципала Kerberos сервера TLS, который клиент TLS будет передавать с, такие как host/mach1.imc.org@IMC.ORG. Серверное приложение TLS нуждается в следующем разрешении.
javax.security.auth.kerberos.ServicePermission(serverPrincipal, "accept");
где serverPrincipal является именем принципала Kerberos сервера TLS, такого как host/mach1.imc.org@IMC.ORG. Если сервер или клиент должны связаться с KDC (например, если его учетные данные не кэшируются локально), это также нуждается в следующем разрешении.
javax.security.auth.kerberos.ServicePermission(tgtPrincipal, "initiate");
где tgtPrincipal является основным именем KDC, такого как krbtgt/IMC.ORG@IMC.ORG.

Дополнительные Форматы Keystore (PKCS12)

PKCS#12 (Стандарт Синтаксиса Exchange Персональных данных) определяет переносимый формат для хранения и/или транспорта закрытых ключей пользователя, сертификатов, разных секретов, и других элементов. SunJSSE провайдер предоставляет полную реализацию PKCS12 java.security.KeyStore формат для чтения и записи pkcs12 файлы. Этот формат также поддерживается другими инструментариями и приложениями для импорта и экспорта ключей и сертификатов, таких как Netscape/Mozilla, Internet Explorer Microsoft, и OpenSSL. Например, эти реализации могут экспортировать клиентские сертификаты и ключи в файл, используя ".p12" расширение файла.

С SunJSSE провайдер, можно получить доступ к ключам PKCS12 через API KeyStore с keystore типом "pkcs12" (или "PKCS12", имя является нечувствительным к регистру). Кроме того, можно перечислить установленные ключи и связанные сертификаты, используя keytool команду с -storetype набор опции к pkcs12. (См. Средства обеспечения безопасности для информации о keytool.)

Поиск и устранение неисправностей

Проблемы конфигурации

CertificateException: (квитируя)

Проблема: Когда согласование соединения SSL, клиента или сервера бросает CertificateException.

Причина 1: Это обычно вызывается удаленной стороной, отправляющей сертификат, который неизвестен локальной стороне.

Решение 1: лучший способ отладить этот тип проблемы состоит в том, чтобы включить отладку (см. Утилиты отладки), и часы как сертификаты загружаются и когда сертификаты получаются через сетевое соединение. Наиболее вероятно полученный сертификат неизвестен доверительному механизму, потому что неправильный доверительный файл был загружен. Отошлите следующие разделы для получения дополнительной информации:

Причина 2: системные часы не устанавливаются правильно.

Решение 2: Если часы не устанавливаются правильно, воспринятое время может быть вне срока действия на одном из сертификатов, и если сертификат может быть заменен допустимым из базы доверенных сертификатов, система должна предположить, что сертификат недопустим, и поэтому выдайте исключение.

java.security. KeyStoreException: TrustedCertEntry, не поддерживаемый

Проблема: Попытайтесь сохранить сертификаты, которым доверяют, в PKCS12 keystore броски java.security.KeyStoreException: TrustedCertEntry not supported.

Причина 1: Мы не поддерживаем хранение сертификаты, которым доверяют, в pkcs12 keystore. PKCS12, главным образом, используется, чтобы поставить закрытые ключи со связанными цепочками свидетельства. У этого нет никакого понятия "доверяемых" сертификатов. Отметьте, что с точки зрения функциональной совместимости, у других pkcs12 поставщиков есть то же самое ограничение. Браузеры, такие как Mozilla и Internet Explorer не принимают pkcs12 файл с только доверяемым certs.

Решение 1: Используйте JKS (или JCEKS) keystore для того, чтобы сохранить доверял сертификатам.

Исключение на этапе выполнения: Служба SSL, Не Доступная

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

    Exception in thread "main"
        java.net.SocketException: no SSL Server Sockets

    Exception in thread "main":
        SSL implementation not available

Причина: была проблема с SSLContext инициализация, например из-за неправильного пароля на keystore или поврежденном keystore. (Отметьте: поставщик JDK, однажды поставленный keystore в неизвестном формате, и это вызвало этот тип ошибки.)

Решение: Проверьте параметры инициализации. Гарантируйте, что любые определенные keystores допустимы и что определенные пароли корректны. (Один способ, которым можно проверить эти вещи, пытаясь использовать keytool, чтобы исследовать keystore (s) и соответствующее содержание.)

Исключение, "Никакой доступный сертификат, соответствующий комплектам шифра SSL, которые включаются"

Проблема: Когда я пытаюсь выполнить простую программу Сервера SSL, следующее исключение выдается:

Exception in thread "main" javax.net.ssl.SSLException:
No available certificate corresponding to the SSL
cipher suites which are enabled...

Причина: Различные комплекты шифра требуют определенных типов ключевого материала. Например, если комплект шифра RSA включается, RSA keyEntry должно быть доступным в keystore. Если никакой такой ключ не доступен, этот комплект шифра не может использоваться. Если нет никаких доступных ключевых записей для всех включенных комплектов шифра, это исключение выдается.

Решение: записи ключа Create для различных типов комплекта шифра, или использование анонимный комплект. (Знайте, что анонимный ciphersuites по сути опасны, потому что они уязвимы для атак "человек в середине", см. RFC 2246.) Обращаются к следующим разделам, чтобы изучить, как передать корректный keystore и сертификаты:

Исключение на этапе выполнения: Никакие Комплекты Шифра вместе

Проблема 1: квитируя, клиент и/или сервер выдают это исключение.

Причина 1: Обе стороны соединения SSL должны договориться об общем ciphersuite. Если пересечение группы ciphersuite клиента с набором ciphersuite сервера будет пусто, то Вы будете видеть это исключение.

Решение 1: Сконфигурируйте включенные комплекты шифра, чтобы включать общий ciphersuites, и убедиться, что обеспечили соответствующее keyEntry для асимметричного ciphersuites. (См. Исключение, "Никакой доступный сертификат..." в этом разделе.)

Проблема 2: При использовании Навигатора Netscape или Microsoft Internet Explorer (IE), чтобы получить доступ к файлам на сервере, у которого только есть основанные на DSA сертификаты, исключение на этапе выполнения происходит, указывая, что нет никаких комплектов шифра вместе.

Причина 2: По умолчанию, keyEntries создаваемый с keytool используют открытые ключи DSA. Если только DSA keyEntries существуйте в keystore, только основанный на DSA ciphersuites может использоваться. По умолчанию Навигатор и IE отправляют только RSA-на-основе ciphersuites. Так как пересечение клиента и сервера ciphersuite наборы пусто, это исключение выдается.

Решение 2: Чтобы взаимодействовать с Навигатором или IE, следует создать сертификаты тот RSA-based использования ключи. Чтобы сделать это, Вы должны определить -keyalg Опция RSA при использовании keytool. Например:

    keytool -genkeypair -alias duke \
        -keystore testkeys -keyalg rsa

Медлительность Первого Доступа JSSE

Проблема: JSSE, кажется, останавливается на первом доступе.

Причина: у JSSE должен быть безопасный источник случайных чисел. Инициализация требует времени.

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

SecureRandom sr = new SecureRandom();
sr.nextInt();
SSLContext.init(..., ..., sr);
<java-home>/lib/security/java.security файл также обеспечивает способ определить источник данных семени для SecureRandom: см. файл для получения дополнительной информации.

Код Используя HttpsURLConnection Броски класса ClassCastException в JSSE 1.0.x

Проблема: следующий фрагмент кода был записан, используя JSSE 1.0.x's com.sun.net.ssl.HttpsURLConnection.

import com.sun.net.ssl.*;
...deleted...
HttpsURLConnection urlc = new URL("https://foo.com/").openConnection();
Работая при этом выпуске, этот код возвращает a javax.net.ssl.HttpsURLConnection и броски a ClassCastException.

Причина: По умолчанию открытие "https" URL создаст a javax.net.ssl.HttpsURLConnection.

Решение: Предыдущие выпуски JDK (теперь известный как Java SE 6 SDK) не поставляли с "https" URL implemention. JSSE 1.0.x реализация действительно обеспечивала такой "https" обработчик URL, и инструкцию по установке, описанную, как установить путь поиска обработчика URL, чтобы получить JSSE 1.0.x com.sun.net.ssl.HttpsURLConnection реализация.

В этом выпуске в пути поиска обработчика URL по умолчанию есть теперь "https" обработчик. Это возвращает экземпляр javax.net.ssl.HttpsURLConnection. Предварительно ожидая старый JSSE 1.0.x путь реализации к пути поиска URL через java.protocol.handler.pkgs переменная, можно все еще получить a com.sun.net.ssl.HttpsURLConnection, и код больше не будет выдавать исключения броска.

% java -Djava.protocol.handler.pkgs=\
  com.sun.net.ssl.internal.www.protocol YourClass
или
System.setProperty("java.protocol.handler.pkgs",
                   "com.sun.net.ssl.internal.www.protocol");

Сокет, Разъединенный после Отправки ClientHello Сообщение

Проблема: сокет пытается соединиться, отправляет a ClientHello сообщение, и было сразу разъединено.

Причина: Некоторые серверы SSL/TLS разъединятся если a ClientHello сообщение получается в формате, который оно не понимает или с номером версии протокола, который оно не поддерживает.

Решение: Попытайтесь корректировать протоколы в SSLSocket.setEnabledProtocols. Например, некоторые более старые реализации сервера говорят только SSLv3 и не понимают TLS. Идеально, эти реализации должны согласовать к SSLv3, но некоторым просто зависание. Для назад совместимости некоторые реализации сервера (такие как SunJSSE) могут отправить SSLv3/TLS ClientHellos инкапсулировавший в SSLv2 ClientHello пакет. Провайдер SunJSSE поддерживает эту функцию, но это не включается по умолчанию. Если Вы хотите использовать эту функцию, вызвать setEnabledProtocols включать SSLv2Hello, который является отправкой инкапсулировавшего SSLv2 ClientHellos.

SunJSSE не может найти провайдера JCA/JCE, который поддерживает необходимый алгоритм и причины NoSuchAlgorithmException

Проблема: квитирование предпринимается, и перестало работать, когда оно не может найти необходимый алгоритм. Примеры могли бы включать:

Exception in thread ...deleted...
     ...deleted...
     Caused by java.security.NoSuchAlgorithmException: Cannot find any
provider supporting RSA/ECB/PKCS1Padding
или
     Caused by java.security.NoSuchAlgorithmException: Cannot find any
provider supporting AES/CBC/NoPadding

Причина: SunJSSE использует JCE для всех своих криптографических алгоритмов. По умолчанию Oracle JDK будет использовать Стандартный ClassLoder Расширения, чтобы загрузить провайдера SunJCE, расположенного в <java-home>/lib/ext/sunjce_provider.jar. Если файл не может быть найден или загружен, или если провайдер SunJCE был вычеркнут из списка от Provider механизм и альтернативная реализация от JCE не доступны, это исключение будет замечено.

Решение: Гарантируйте, что SunJCE доступен, проверяя, что файл загружаем и что провайдер регистрируется в Provider интерфейс. Попытайтесь выполнить следующий код в контексте Вашего соединения SSL.

    import javax.crypto.*;

    System.out.println("=====Where did you get AES=====");
    Cipher c = Cipher.getInstance("AES/CBC/NoPadding");
    System.out.println(c.getProvider());

Утилиты отладки

JSSE оказывает динамическую поддержку трассировки отладки. Это подобно поддержке, используемой для того, чтобы отладить отказы управления доступом в Java SE 6 платформ. К универсальному Java динамическая поддержка трассировки отладки получают доступ с системным свойством java.security.debug, в то время как к JSSE-специфичной динамической поддержке трассировки отладки получают доступ с системным свойством javax.net.debug.

Отметьте: утилита отладки не является официально поддерживавшей функцией JSSE.

Чтобы просмотреть опции динамической утилиты отладки JSSE, используйте следующий параметр командной строки на java команда:

    -Djavax.net.debug=help

Отметьте: Если Вы определяете значение help с любой динамической утилитой отладки, выполняя программу, которая не использует классов, которые утилита была разработана, чтобы отладить, Вы не будете получать опции отладки.

Вот полный пример того, как получить список опций отладки:

    java -Djavax.net.debug=help MyApp
где MyApp является приложением, которое использует некоторые из классов JSSE. MyApp не будет бежать за справочной информацией отладки, печатается, поскольку код справки заставляет приложение выходить.

Вот текущие опции:

        all        turn on all debugging
        ssl        turn on ssl debugging

        The following can be used with ssl:
            record          enable per-record tracing
            handshake       print each handshake message
            keygen          print key generation data
            session         print session activity
            defaultctx      print default SSL initialization
            sslctx          print SSLContext tracing
            sessioncache    print session cache tracing
            keymanager      print key manager tracing
            trustmanager    print trust manager tracing

        handshake debugging can be widened with:
            data            hex dump of each handshake message
            verbose         verbose handshake message printing

        record debugging can be widened with:
            plaintext       hex dump of record plaintext
            packet          print raw SSL/TLS packets

javax.net.debug значение свойства должно определить также all или ssl, дополнительно сопровождаемый спецификаторами отладки. Можно использовать одну или более опций. У Вас не должно быть разделителя между опциями, хотя разделитель, такой как ":" или"," помогает удобочитаемости. Не имеет значения, какие разделители Вы используете, и упорядочивание ключевых слов опции также не важно.

Для введения при чтении этой отладочной информации, пожалуйста, обратитесь к руководству, Отлаживая Соединения SSL/TLS.

Примеры

Примеры кода

Разделы ниже описывают следующие примеры кода:

Преобразование Незащищенного сокета к Защищенному сокету

Этот раздел обеспечивает примеры исходного кода, которые иллюстрируют, как использовать JSSE, чтобы преобразовать соединение незащищенного сокета с соединением защищенного сокета. Код в этом разделе выбирается от книжного Java SE 6 сетевой безопасности с помощью Марко Пистоиы, и. al.

Во-первых, "Пример Сокета Без SSL" показывает пример кода, который может использоваться, чтобы установить передачу между клиентом и сервером, используя незащищенные сокеты. Этот код тогда изменяется в "Примере Сокета С SSL", чтобы использовать JSSE, чтобы установить передачу защищенного сокета.

Пример сокета Без SSL

Серверный код для Связи Незащищенного сокета

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

import java.io.*;
import java.net.*;

. . .

int port = availablePortNumber;

ServerSocket s;

try {
    s = new ServerSocket(port);
    Socket c = s.accept();

    OutputStream out = c.getOutputStream();
    InputStream in = c.getInputStream();

    // Send messages to the client through
    // the OutputStream
    // Receive messages from the client
    // through the InputStream
}

catch (IOException e) {
}

Клиентский Код для Связи Незащищенного сокета

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

import java.io.*;
import java.net.*;

. . .

int port = availablePortNumber;
String host = "hostname";

try {
    s = new Socket(host, port);

    OutputStream out = s.getOutputStream();
    InputStream in = s.getInputStream();

    // Send messages to the server through
    // the OutputStream
    // Receive messages from the server
    // through the InputStream
}

catch (IOException e) {
}

Пример сокета С SSL

Серверный код для Связи Защищенного сокета

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

import java.io.*;
import javax.net.ssl.*;

. . .

int port = availablePortNumber;

SSLServerSocket s;

try {
    SSLServerSocketFactory sslSrvFact =
        (SSLServerSocketFactory)
        SSLServerSocketFactory.getDefault();
    s =(SSLServerSocket)sslSrvFact.createServerSocket(port);

    SSLSocket c = (SSLSocket)s.accept();

    OutputStream out = c.getOutputStream();
    InputStream in = c.getInputStream();

    // Send messages to the client through
    // the OutputStream
    // Receive messages from the client
    // through the InputStream
}

catch (IOException e) {
}

Клиентский Код для Связи Защищенного сокета

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

import java.io.*;
import javax.net.ssl.*;

. . .

int port = availablePortNumber;
String host = "hostname";

try {
    SSLSocketFactory sslFact =
      (SSLSocketFactory)SSLSocketFactory.getDefault();
    SSLSocket s =
      (SSLSocket)sslFact.createSocket(host, port);

    OutputStream out = s.getOutputStream();
    InputStream in = s.getInputStream();

    // Send messages to the server through
    // the OutputStream
    // Receive messages from the server
    // through the InputStream
}

catch (IOException e) {
}

Выполнение Примера кода JSSE

Примеры программ JSSE иллюстрируют, как использовать JSSE для:

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

Отметьте: Установка безопасной связи включает сложные алгоритмы. Примеры программ не обеспечивают обратной связи во время процесса установки. Выполняя программы, быть терпеливым: Вы не можете видеть вывод некоторое время. Если Вы выполняете программы с системным свойством javax.net.debug набор к all, Вы будете видеть больше обратной связи. Для введения при чтении этой отладочной информации обратитесь к руководству, Отлаживая Соединения SSL/TLS.

Где Найти Пример кода

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

Разделы ниже описывают выборки. См. README для дополнительной информации.

Пример кода, Иллюстрирующий Соединение Защищенного сокета Между Клиентом и Сервером

Примеры программ в samples/sockets каталог иллюстрирует, как установить соединение защищенного сокета между клиентом и сервером.

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

Вся выборка SSLSocketClient* программы в samples/sockets/client каталог (и программы URLReader*, описанные в Примере кода, Иллюстрирующем Соединения HTTPS), может быть выполнен с ClassFileServer демонстрационная программа сервера. Пример того, как сделать это, показывают в Выполнении SSLSocketClientWithClientAuth с ClassFileServer. Можно произвести подобные изменения, чтобы работать URLReader, SSLSocketClient или SSLSocketClientWithTunneling с ClassFileServer.

Если ошибка аутентификации происходит, пытаясь отправить сообщения между клиентом и сервером (использовать ли ли веб-сервер или ClassFileServer), это наиболее вероятно, потому что необходимые ключи не находятся в базе доверенных сертификатов (доверительная ключевая база данных). Например, ClassFileServer использует keystore, названный "testkeys", содержащим закрытый ключ для "localhost" как необходимый во время квитирования SSL. ("testkeys" включается в то же самое samples/sockets/server каталог как ClassFileServer источник.), Если клиент не может найти сертификат для соответствующего открытого ключа "localhost" в базе доверенных сертификатов, это консультируется, ошибка аутентификации произойдет. Убедитесь, что использовали samplecacerts база доверенных сертификатов (который содержит "localhost" s открытый ключ / свидетельство), как описано в следующем разделе.

Требования конфигурации

Выполняя примеры программ, которые создают соединение защищенного сокета между клиентом и сервером, Вы должны будете сделать соответствующий файл сертификатов (база доверенных сертификатов) доступный. И для клиента и для программ сервера, следует использовать файл сертификатов samplecacerts от samples каталог. Используя этот файл сертификатов позволит клиенту аутентифицировать сервер. Файл содержит все общие сертификаты Центра сертификации, поставленные с JDK (в cacerts файл), плюс сертификат для "localhost", необходимого клиенту, чтобы аутентифицировать "localhost", связываясь с демонстрационным сервером ClassFileServer. (ClassFileServer использует keystore, содержащий закрытый ключ для "localhost", который соответствует открытому ключу в samplecacerts. )

Сделать samplecacerts файл, доступный и клиенту и серверу, можно или скопировать это в файл <java-home>/lib/security/jssecacerts, переименуйте это cacerts и используйте это, чтобы заменить <java-home>/lib/security/cacerts файл, или добавляют следующую опцию к командной строке, работая java команда и для клиента и для сервера:

-Djavax.net.ssl.trustStore=path_to_samplecacerts_file

(См. Каталог Установки <дом Java> для информации о какой <java-home> обращается к.)

Пароль для samplecacerts база доверенных сертификатов changeit. Можно заменить своими собственными сертификатами в выборках, используя keytool.

Если Вы используете браузер, такой как Навигатор Netscape или Internet Explorer Microsoft, чтобы получить доступ к демонстрационному серверу SSL, обеспеченному в ClassFileServer пример, диалоговое окно может раскрыться с сообщением, что это не распознает сертификат. Это нормально, потому что сертификат, используемый с примерами программ, самоподписывается и для того, чтобы протестировать только. Можно принять сертификат для текущего сеанса. После тестирования сервера SSL следует выйти из браузера, который удаляет свидетельство об испытании из пространства имен браузера.

Для аутентификации клиента отдельный сертификат "герцога" доступен в соответствующих каталогах. Открытый ключ / сертификат также сохранен в samplecacerts файле.

Выполнение SSLSocketClient

Программа SSLSocketClient.java демонстрирует, как создать клиент, чтобы использовать SSLSocket отправить запрос HTTP и получить ответ от сервера HTTPS. Вывод этой программы является источником HTML для https://www.verisign.com/index.html.

Не следует быть позади брандмауэра, чтобы выполнить эту программу как поставлено. Если Вы выполните это из-за брандмауэра, то Вы доберетесь UnknownHostException потому что JSSE не может найти путь через Ваш брандмауэр к www.verisign.com. Чтобы создать эквивалентный клиент, который может работать из-за брандмауэра, установите прокси, туннелирующий как иллюстрировано в примере программы SSLSocketClientWithTunneling.

Выполнение SSLSocketClientWithTunneling

Программа SSLSocketClientWithTunneling.java иллюстрирует, как сделать прокси, туннелирующий, чтобы получить доступ к безопасному веб-серверу из-за брандмауэра. Чтобы выполнить эту программу, следует установить следующие системные свойства Java в соответствующие значения:

java -Dhttps.proxyHost=webproxy
-Dhttps.proxyPort=ProxyPortNumber
SSLSocketClientWithTunneling

Отметьте: спецификации Прокси с -D опции (показанный в синем) являются дополнительными. Кроме того, убедиться, что заменил webproxy с именем Вашего узла прокси и ProxyPortNumber с соответствующим номером порта.

Программа возвратит исходный файл HTML из https://www.verisign.com/index.html.

Выполнение SSLSocketClientWithClientAuth

Программа SSLSocketClientWithClientAuth.java показывает, как установить ключевого менеджера, чтобы сделать аутентификацию клиента если требующийся сервером. Эта программа также предполагает, что клиент не вне брандмауэра. Можно изменить программу, чтобы соединиться изнутри брандмауэра, следуя примеру в SSLSocketClientWithTunneling.

Чтобы выполнить эту программу, следует определить три параметра: узел, порт, и требуемый путь к файлу. Чтобы зеркально отразить предыдущие примеры, можно выполнить эту программу без аутентификации клиента, устанавливая узел www.verisign.com, порт к 443, и требуемый путь к файлу к https://www.verisign.com/. Вывод при использовании этих параметров является HTML для Веб-сайта https://www.verisign.com/.

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

Выполнение ClassFileServer

Программа, упомянутая здесь как ClassFileServer составляется из двух файлов, ClassFileServer.java и ClassServer.java.

Чтобы выполнить их, работать ClassFileServer.class, который требует следующих параметров:

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

Отметьте 2: сервер ожидает, ДОБИРАЮТСЯ, запросы в форме "ДОБИРАЮТСЯ/... ", где"..." путь к файлу.

Выполнение SSLSocketClientWithClientAuth С ClassFileServer

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

  1. Выполните программу ClassFileServer от одной машины или окна терминала, как описано в Выполнении ClassFileServer.
  2. Выполните программу SSLSocketClientWithClientAuth на другой машине или окне терминала. SSLSocketClientWithClientAuth требует следующих параметров:
ОТМЕТЬТЕ: можно изменить команды "GET" другого приложения SSLClient*, чтобы соединиться с локальным машинным выполнением ClassFileServer.

Пример кода, Иллюстрирующий Соединения HTTPS

Есть два основных API для того, чтобы получить доступ к безопасной связи через JSSE. Один путь через API на уровне сокета, который может использоваться для произвольной безопасной связи, как иллюстрировано SSLSocketClient, SSLSocketClientWithTunneling, и SSLSocketClientWithClientAuth (с и без ClassFileServer) примеры программ.

Секунда, и часто более простой путь, являются через стандартный Java API URL. Можно связаться надежно с поддерживающим SSL веб-сервером при использовании "https" протокола URL или схемы, используя java.net.URL класс.

Поддержка "https" схем URL реализуется во многих из общих браузеров, который предоставляет доступ к защищенной связи, не требуя API на уровне сокета, предоставленного JSSE.

Пример URL мог бы быть:

"https://www.verisign.com"

Доверительное и управление ключами для "https" реализации URL специфично для среды. Реализация JSSE обеспечивает "https" реализацию URL. Если Вы хотите, чтобы различная https реализация протокола использовалась, можно установить java.protocol.handler.pkgs системное свойство к имени пакета. См. java.net.URL документация класса для деталей.

Выборки, которые можно загрузить JSSE, включают два примера программ, которые иллюстрируют, как создать соединение HTTPS. Оба из этих примеров программ, URLReader.java и URLReaderWithOptions.java находятся в urls каталог.

Выполнение URLReader

Программа URLReader.java иллюстрирует использование класса URL, чтобы получить доступ к безопасному сайту. Вывод этой программы является источником HTML для https://www.verisign.com/. По умолчанию реализация протокола HTTPS, включенная с JSSE, будет использоваться. Если Вы хотите использовать различную реализацию, следует установить системное свойство java.protocol.handler.pkgs значение, чтобы быть именем пакета, содержащего реализацию.

Если Вы выполняете пример кода позади брандмауэра, следует установить системные свойства https.proxyHost и https.proxyPort. Например, чтобы использовать узел прокси "webproxy" на порту 8080, можно использовать следующие опции для java команда:

-Dhttps.proxyHost=webproxy
-Dhttps.proxyPort=8080

Альтернативно, можно установить системные свойства в пределах исходного кода с java.lang.System метод setProperty. Например, вместо того, чтобы использовать параметры командной строки, можно включать следующие строки в свою программу:

System.setProperty("java.protocol.handler.pkgs",
    "com.ABC.myhttpsprotocol");

System.setProperty("https.proxyHost",
    "webproxy");

System.setProperty("https.proxyPort",
    "8080");

Отметьте: работая на Windows 95 или Windows 98, максимального количества символов, позволенных в подсказке MS-DOS, возможно, не достаточно, чтобы включать все параметры командной строки. Если Вы встречаетесь с этой проблемой, или создаете.bat файл со всей командой или добавляете системные свойства к исходному коду, и перекомпилируйте исходный код.

Выполнение URLReaderWithOptions

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

Чтобы выполнить URLReaderWithOptions, введите следующую команду (все на одной строке):

java URLReaderWithOptions
     [-h proxyhost -p proxyport]
     [-k protocolhandlerpkgs]
     [-c ciphersarray]
     myApp

Отметьте: Многократные обработчики протокола могут быть включены в protocolhandlerpkgs в списке с элементами, разделенными вертикальными панелями. Многократные имена комплекта шифра SSL могут быть включены в ciphersarray в списке с элементами, разделенными запятыми. Возможные имена комплекта шифра являются тем же самым как возвращенными вызовом SSLSocket.getSupportedCipherSuites(). Имена комплекта берутся от SSL и спецификаций протокола TLS.

Вы только нуждаетесь в a protocolhandlerpkgs параметр, если Вы хотите использовать реализацию обработчика протокола HTTPS кроме значения по умолчанию один обеспеченный Oracle.

Если Вы работаете позади брандмауэра, следует включать параметры за узел прокси и порт прокси. Дополнительно, можно включать список комплектов шифра, чтобы включить.

Вот пример выполнения URLReaderWithOptions и определения, что прокси размещает "webproxy" на порту 8080:

java URLReaderWithOptions
    -h webproxy -p 8080

Пример кода, Иллюстрирующий Безопасное Соединение RMI

Пример кода в samples/rmi каталог иллюстрирует, как создать безопасное соединение RMI. Пример кода основан на примере RMI, который является в основном "Привет Мировым" примером, измененным, чтобы установить и использовать пользовательскую фабрику сокета RMI.

Для получения дополнительной информации о RMI, см. Java документация RMI. Эта Веб-страница указывает на учебные руководства RMI и другую информацию о RMI.

Пример кода, Иллюстрирующий Использование SSLEngine

SSLEngine был представлен в Java SE 5 выпусков Java 2 Платформы, чтобы дать гибкость разработчиков приложений, выбирая ввод-вывод и вычислить стратегии. Вместо того, чтобы связывать реализацию SSL/TLS с определенной абстракцией ввода-вывода (такой как однопоточную SSLSockets), SSLEngine удаляет ввод-вывод, и вычислите ограничения из реализации SSL/TLS.

Как отмечалось ранее, SSLEngine усовершенствованный API, и не является подходящим для случайного использования. Некоторый introductary пример кода обеспечивается здесь, который помогает иллюстрировать его использование. Первый демонстрационный пример удаляет большую часть ввода-вывода и распараллеливающих проблем, и сосредотачивается на многих из методов SSLEngine. Второй демонстрационный пример является более реалистическим примером, показывающим как SSLEngine мог бы быть объединен с Java NIO, чтобы создать элементарный сервер HTTP/HTTPS.

Выполнение SSLEngineSimpleDemo

SSLEngineSimpleDemo является очень простым приложением, которое сосредотачивается на работе SSLEngine упрощая ввод-вывод и распараллеливая проблемы. Это приложение создает два SSLEngines, которые обмениваются сообщениями SSL/TLS через общий ByteBuffers. Единственный цикл последовательно выполняет все операции механизма и демонстрирует, как безопасное соединение устанавливается (квитируя), как данные приложения передаются, и как механизм закрывается.

SSLEngineResult предоставляет большую информацию о SSLEngine's текущее состояние. Этот пример не исследует все состояния. Это упрощает ввод-вывод и распараллеливающие проблемы до такой степени, что это не хороший пример для продуктивной среды; тем не менее, полезно демонстрировать полную функцию SSLEngine.

Выполнение NIOНа основе Сервер


Отметьте: пример сервера, обсужденный в этом разделе, включается в Java Комплект разработчика 6 SE. Можно счесть код связанным в <jdk-home>/samples/nio/server каталог.
Полностью использовать гибкость, обеспеченную SSLEngine, нужно сначала понять дополнительный API, такой как ввод-вывод и модели потоков.

Модель ввода-вывода, которую крупномасштабные разработчики приложений находят использования, является NIO SocketChannels. NIO был представлен частично, чтобы решить часть масштабирующейся проблемы, свойственной от java.net. API сокета. У SocketChannels есть много различных режимов работы включая:

Пример кода для скелеты, которые - сервер HTTP то, при условии, что не только демонстрирует многие из новых API NIO, и также показывает как SSLEngine может использоваться, чтобы создать безопасный сервер HTTPS. Сервер не является производственным качеством, но действительно показывает многие из этих новых API в действии.

В демонстрационном каталоге README.txt файл, который представляет сервер, объясняет, как создать и сконфигурировать, и обеспечивает краткий обзор размещения кода. Файлы большинства интереса для SSLEngine пользователи ChannelIO.java и ChannelIOSecure.java.

Создание Keystore, чтобы Использовать с JSSE

Создание Простого Keystore и Базы доверенных сертификатов

В этом разделе мы будем использовать keytool создать простой JKS keystore подходящий для использования с JSSE. Мы сделаем a keyEntry (с общественностью/закрытыми ключами) в keystore, затем сделайте соответствие trustedCertEntry (открытые ключи только) в базе доверенных сертификатов. (Для аутентификации клиента Вы должны будете сделать подобный процесс для сертификатов клиента.) Примечание: Хранение доверительных привязок в PKCS12 не поддерживается. Пользователи должны использовать JKS для того, чтобы сохранить доверительные привязки и PKCS12 для закрытых ключей. Отметьте: Это выходит за рамки этого примера, чтобы объяснить каждый шаг подробно. Если Вы нуждаетесь в большей информации, пожалуйста, см. keytool документацию для Соляриса или Microsoft Windows. Ввод данных пользователем показывают в полужирном шрифте.
  1. Создайте новый keystore и самоподписанный сертификат с соответствующей общественностью/закрытыми ключами.
    % keytool -genkeypair -alias duke -keyalg RSA \
      -validity 7 -keystore keystore 
    
     Enter keystore password:  password
     What is your first and last name?
     [Unknown]:  Duke
     What is the name of your organizational unit?
     [Unknown]:  Java Software
     What is the name of your organization?
     [Unknown]:  Oracle, Inc.
     What is the name of your City or Locality?
     [Unknown]:  Palo Alto
     What is the name of your State or Province?
     [Unknown]:  CA
     What is the two-letter country code for this unit?
     [Unknown]:  US
     Is CN=Duke, OU=Java Software, O="Oracle, Inc.",
     L=Palo Alto, ST=CA, C=US correct?
     [no]:  yes
    
     Enter key password for <duke>
      (RETURN if same as keystore password):  <CR>
    
    
    Это - keystore, который будет использовать сервер.
  2. Исследуйте keystore. Заметьте, что тип записи keyEntry что означает, что у этой записи есть закрытый ключ, связанный с этим (показанный в красном).
    % keytool -list -v -keystore keystore
    Enter keystore password:  password
    
    Keystore type: jks
    Keystore provider: SUN
    
    Your keystore contains 1 entry
    
    Alias name: duke
    Creation date: Dec 20, 2001
    Entry type: keyEntry
    Certificate chain length: 1
    Certificate[1]:
    Owner: CN=Duke, OU=Java Software, O="Oracle, Inc.",
    L=Palo Alto, ST=CA, C=US
    Issuer: CN=Duke, OU=Java Software, O="Oracle, Inc.", L=Palo Alto, ST=CA, C=US
    Serial number: 3c22adc1
    Valid from: Thu Dec 20 19:34:25 PST 2001 until: Thu Dec 27 19:34:25 PST 2001
    Certificate fingerprints:
        MD5: F1:5B:9B:A1:F7:16:CF:25:CF:F4:FF:35:3F:4C:9C:F0
        SHA1: B2:00:50:DD:B6:CC:35:66:21:45:0F:96:AA:AF:6A:3D:E4:03:7C:74
    
    
  3. Экспортируйте и исследуйте самоподписанный сертификат.
    % keytool -export -alias duke -keystore keystore -rfc \
      -file duke.cer
    Enter keystore password:  password
    Certificate stored in file <duke.cer>
    % cat duke.cer
    -----BEGIN CERTIFICATE-----
    MIICXjCCAccCBDwircEwDQYJKoZIhvcNAQEEBQAwdjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNB
    MRIwEAYDVQQHEwlQYWxvIEFsdG8xHzAdBgNVBAoTFlN1biBNaWNyb3N5c3RlbXMsIEluYy4xFjAU
    BgNVBAsTDUphdmEgU29mdHdhcmUxDTALBgNVBAMTBER1a2UwHhcNMDExMjIxMDMzNDI1WhcNMDEx
    MjI4MDMzNDI1WjB2MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVBhbG8gQWx0
    bzEfMB0GA1UEChMWU3VuIE1pY3Jvc3lzdGVtcywgSW5jLjEWMBQGA1UECxMNSmF2YSBTb2Z0d2Fy
    ZTENMAsGA1UEAxMERHVrZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1loObJzNXsi5aSr8
    N4XzDksD6GjTHFeqG9DUFXKEOQetfYXvA8F9uWtz8WInrqskLTNzwXgmNeWkoM7mrPpK6Rf5M3G1
    NXtYzvxyi473Gh1h9k7tjJvqSVKO7E1oFkQYeUPYifxmjbSMVirWZgvo2UmA1c76oNK+NhoHJ4qj
    eCUCAwEAATANBgkqhkiG9w0BAQQFAAOBgQCRPoQYw9rWWvfLPQuPXowvFmuebsTc28qI7iFWm6BJ
    TT/qdmzti7B5MHOt9BeVEft3mMeBU0CS2guaBjDpGlf+zsK/UUi1w9C4mnwGDZzqY/NKKWtLxabZ
    5M+4MAKLZ92ePPKGpobM2CPLfM8ap4IgAzCbBKd8+CMp8yFmifze9Q==
    -----END CERTIFICATE-----
    
    
    Альтернативно, Вы могли генерировать Запрос Подписания Сертификата (CSR) с -certreq и отправьте это Центру сертификации (CA) для того, чтобы подписаться, но снова, это выходит за рамки этого примера.
  4. Импортируйте сертификат в новую базу доверенных сертификатов.
    % keytool -import -alias dukecert -file duke.cer \
      -keystore truststore
    Enter keystore password:  trustword
    Owner: CN=Duke, OU=Java Software, O="Oracle, Inc.", L=Palo Alto, ST=CA, C=US
    Issuer: CN=Duke, OU=Java Software, O="Oracle, Inc.", L=Palo Alto, ST=CA, C=US
    Serial number: 3c22adc1
    Valid from: Thu Dec 20 19:34:25 PST 2001 until: Thu Dec 27 19:34:25 PST 2001
    Certificate fingerprints:
        MD5: F1:5B:9B:A1:F7:16:CF:25:CF:F4:FF:35:3F:4C:9C:F0
        SHA1: B2:00:50:DD:B6:CC:35:66:21:45:0F:96:AA:AF:6A:3D:E4:03:7C:74
    Trust this certificate? [no]:  yes
    Certificate was added to keystore
    
    
  5. Исследуйте базу доверенных сертификатов. Отметьте, что тип записи trustedCertEntry, что означает, что закрытый ключ не доступен для этой записи (показанный в красном). Это также означает, что этот файл не является подходящим как a KeyManager's keystore.
    % keytool -list -v -keystore truststore
    Enter keystore password:  trustword
    
    Keystore type: jks
    Keystore provider: SUN
    
    Your keystore contains 1 entry
    
    Alias name: dukecert
    Creation date: Dec 20, 2001
    Entry type: trustedCertEntry
    
    Owner: CN=Duke, OU=Java Software, O="Oracle, Inc.", L=Palo Alto, ST=CA, C=US
    Issuer: CN=Duke, OU=Java Software, O="Oracle, Inc.", L=Palo Alto, ST=CA, C=US
    Serial number: 3c22adc1
    Valid from: Thu Dec 20 19:34:25 PST 2001 until: Thu Dec 27 19:34:25 PST 2001
    Certificate fingerprints:
        MD5: F1:5B:9B:A1:F7:16:CF:25:CF:F4:FF:35:3F:4C:9C:F0
        SHA1: B2:00:50:DD:B6:CC:35:66:21:45:0F:96:AA:AF:6A:3D:E4:03:7C:74
    
    
    Теперь запустите свои приложения с соответствующими базами ключей. Этот пример принимает значение по умолчанию X509KeyManager и X509TrustManager используются, таким образом мы выберем keystores использование системных свойств, описанных в Настройке.
    % java -Djavax.net.ssl.keyStore=keystore \
      -Djavax.net.ssl.keyStorePassword=password Server
    
    % java -Djavax.net.ssl.trustStore=truststore \
      -Djavax.net.ssl.trustStorePassword=trustword Client
    


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

Приложение A: Стандартные имена

API Безопасности JDK требует и использует ряд стандартных имен для алгоритмов, сертификата и типов keystore. Спецификация называет ранее найденным здесь в Приложении A и в других спецификациях безопасности (JCA/CertPath/etc). были объединены в документе Стандартных имен. Определенная информация о провайдере может быть найдена в Oracle Provider Documentation.

Приложение B: Провайдер Pluggability

JSSE в Java SE 6 является полностью сменным и не ограничивает использование третьей стороны провайдеры JSSE всегда.


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