1. Обзор
В этом руководстве мы познакомимся с SSL и рассмотрим, как мы можем использовать его в Java с помощью API JSSE (Java Secure Socket Extension).
2. Введение
Проще говоря, Secured Socket Layer (SSL)
обеспечивает защищенное соединение между двумя сторонами , обычно клиентами и серверами.
SSL обеспечивает безопасный канал между двумя устройствами, работающими через сетевое соединение. Одним из обычных примеров SSL является обеспечение безопасной связи между веб-браузерами и веб-серверами.
В этом конкретном случае веб-браузеры будут использовать соединения HTTPS (S означает защищенные) для доступа к ресурсам, предоставляемым отдельными веб-серверами.
SSL необходим для поддержки трех основных принципов информационной безопасности:
- Шифрование : защита передачи данных между сторонами
- Аутентификация : убедитесь, что сервер, к которому мы подключаемся, действительно является правильным сервером.
- Целостность данных : гарантия того, что запрошенные данные — это то, что эффективно доставляется
Java предоставляет несколько API-интерфейсов, основанных на безопасности, которые помогают разработчикам устанавливать безопасные соединения с клиентом для получения и отправки сообщений в зашифрованном формате:
- Расширение защищенных сокетов Java (JSSE)
- Архитектура криптографии Java (JCA)
- Криптографическое расширение Java (JCE)
В следующих разделах мы представим расширение Secure Socket, которое Java использует для обеспечения безопасного обмена данными.
3. JSSE-API
API-интерфейсы безопасности Java широко используют шаблон проектирования Factory .
На самом деле все создается с помощью фабрики в JSSE.
3.1. SSLSocketFactory
javax.net.ssl.SSLSocketFactory используется для создания объектов
SSLSocket
. ``
Этот класс содержит три группы API.
Первая группа состоит из одного статического метода getDefault()
, используемого для получения экземпляра по умолчанию, который, в свою очередь, может создавать экземпляры SSLSocket
.
Вторая группа состоит из пяти методов, которые можно использовать для создания экземпляров SSLSocket
:
Сокет createSocket (хост String, порт int)
Сокет createSocket(String host, int port, InetAddress clientHost, int clientPort)
Сокет createSocket (хост InetAddress, порт int)
Сокет createSocket (хост InetAddress, порт int, клиентский хост InetAddress, порт клиента int)
Socket createSocket (Socket socket, String host, int port, boolean autoClose)
Мы можем использовать этот класс напрямую, получив экземпляр по умолчанию или используя javax.net.ssl.
Объект SSLContext, который содержит методы для получения экземпляра SSLSocketFactory
.
3.2. SSLSocket
Этот класс расширяет класс Socket
и обеспечивает безопасный сокет. Такие сокеты являются обычными потоковыми сокетами.
Кроме того, они добавляют уровень защиты к основному сетевому транспортному протоколу.
Экземпляры SSLSocket создают
SSL-соединение с именованным хостом на указанном порту.
Это позволяет привязать клиентскую сторону соединения к заданному адресу и порту.
3.3. SSLServerSocketFactory
Класс SSLServerSocketFactory
очень похож на SSLSocketFactory
с той разницей, что он создает экземпляры SSLServerSocket вместо экземпляров
SSLSocket
.
По сходству методы называются createServerSocket
по аналогии с классом SSLSocketFactory
.
3.4. SSLServerSocket
Класс SSLServerSocket
аналогичен классу SSLSocket
. Методы класса SSLServerSocket являются подмножеством методов класса SSLSocket
. Они действуют на противоположной стороне SSL-соединения.
4. Пример SSL
Давайте приведем пример того, как мы можем создать защищенное соединение с сервером:
String host = getHost(...);
Integer port = getPort(...);
SSLSocketFactory sslsocketfactory = SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory
.createSocket(host, port);
InputStream in = sslsocket.getInputStream();
OutputStream out = sslsocket.getOutputStream();
out.write(1);
while (in.available() > 0) {
System.out.print(in.read());
}
System.out.println("Secured connection performed successfully");
В случае, если мы получаем сообщение об ошибке «javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: Ошибка построения пути PKIX: sun.security.provider.certpath.SunCertPathBuilderException: невозможно найти допустимый путь сертификации к запрошенной цели при установлении SSL-соединение»
, это указывает на то, что у нас нет общедоступного сертификата сервера, к которому мы пытаемся подключиться, в хранилище доверенных сертификатов Java.
Хранилище доверенных сертификатов — это файл, содержащий доверенные сертификаты, которые Java использует для проверки защищенных соединений.
Чтобы решить эту проблему, у нас есть несколько вариантов:
- добавьте общедоступный сертификат сервера в хранилище доверенных сертификатов
cacerts
по умолчанию , используемое Java. при запуске SSL-соединения - Установите javax.net.
SSL
.переменная среды trustStore
, указывающая на файл хранилища доверенных сертификатов, чтобы приложение могло подобрать этот файл, содержащий общедоступный сертификат сервера, к которому мы подключаемся.
Шаги для установки нового сертификата в хранилище доверенных сертификатов Java по умолчанию:
- извлечь сертификат с сервера:
openssl s_client -connect server:443
- импортировать сертификат в хранилище доверенных сертификатов с помощью keytool:
keytool -import -alias alias.server.com -keystore $JAVA_HOME/jre/lib/security/cacerts
Как только мы это сделаем, мы сможем снова запустить пример и получить сообщение « Защищенное соединение выполнено успешно
».
5. Вывод
В этой статье мы представили SSL и JSSE API, который реализует SSL для Java. Используя SSL и JSSE, мы можем сделать наши Java-приложения и обмен данными между приложениями и внутри приложения более безопасными.
Как всегда, код, представленный в этой статье, доступен на Github .