Ssl проверка сертификата java

Аутентификация сертификата клиента Java HTTPS

HTTPS — это расширение HTTP, которое обеспечивает безопасную связь между двумя объектами в компьютерной сети. HTTPS использует протокол TLS (Transport Layer Security) для обеспечения безопасных соединений.

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

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

2. Версии Java и TLS​

TLS 1.3 — последняя версия протокола. Эта версия более производительна и безопасна . Он имеет более эффективный протокол рукопожатия и использует современные криптографические алгоритмы.

Java начала поддерживать эту версию протокола в Java 11. Мы будем использовать эту версию для генерации сертификатов и реализации простой пары клиент-сервер, которая использует TLS для аутентификации друг друга.

3. Генерация сертификатов в Java​

Поскольку мы используем двустороннюю аутентификацию TLS , нам нужно сгенерировать сертификаты для клиента и сервера.

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

Читайте также:  Плагины для html таблица

3.1. Сертификат сервера​

Во- первых, мы создаем хранилище ключей сервера :

 keytool -genkey -alias serverkey -keyalg RSA -keysize 2048 -sigalg SHA256withRSA -keystore serverkeystore.p12 -storepass password -ext san=ip:127.0.0.1,dns:localhost 

Мы используем параметр keytool -ext для установки альтернативных имен субъекта (SAN) для определения локального имени хоста/IP-адреса, который идентифицирует сервер. Как правило, с помощью этой опции мы можем указать несколько адресов. Однако клиенты будут вынуждены использовать один из этих адресов для подключения к серверу.

Далее экспортируем сертификат в файл server-certificate.pem :

 keytool -exportcert -keystore serverkeystore.p12 -alias serverkey -storepass password -rfc -file server-certificate.pem 

Наконец, мы добавляем сертификат сервера в хранилище доверенных сертификатов клиента :

 keytool -import -trustcacerts -file server-certificate.pem -keypass password -storepass password -keystore clienttruststore.jks 

3.2. Сертификат клиента​

Точно так же мы создаем хранилище ключей клиента и экспортируем его сертификат:

 keytool -genkey -alias clientkey -keyalg RSA -keysize 2048 -sigalg SHA256withRSA -keystore clientkeystore.p12 -storepass password -ext san=ip:1`27.0.0.1,dns:localhost  keytool -exportcert -keystore clientkeystore.p12 -alias clientkey -storepass password -rfc -file client-certificate.pem  keytool -import -trustcacerts -file client-certificate.pem -keypass password -storepass password -keystore servertruststore.jks 

В последней команде мы добавили сертификат клиента в хранилище доверенных сертификатов сервера .

4. Реализация серверной Java​

При использовании сокетов Java реализация сервера тривиальна. Класс SSLSocketEchoServer получает SSLServerSocket для простой поддержки аутентификации TLS. Нам просто нужно указать шифр и протоколы, а все остальное — это просто стандартный эхо-сервер, который отвечает на те же сообщения, что и клиент:

 public class SSLSocketEchoServer     static void startServer(int port) throws IOException     ServerSocketFactory factory = SSLServerSocketFactory.getDefault();   try (SSLServerSocket listener = (SSLServerSocket) factory.createServerSocket(port))    listener.setNeedClientAuth(true);   listener.setEnabledCipherSuites(new String[]  "TLS_AES_128_GCM_SHA256" >);   listener.setEnabledProtocols(new String[]  "TLSv1.3" >);   System.out.println("listening for messages. ");   try (Socket socket = listener.accept())     InputStream is = new BufferedInputStream(socket.getInputStream());   byte[] data = new byte[2048];   int len = is.read(data);    String message = new String(data, 0, len);   OutputStream os = new BufferedOutputStream(socket.getOutputStream());   System.out.printf("server received %d bytes: %s%n", len, message);   String response = message + " processed by server";   os.write(response.getBytes(), 0, response.getBytes().length);   os.flush();   >   >   >   > 

Сервер прослушивает клиентские соединения. Для вызова listener.setNeedClientAuth(true) клиент должен поделиться своим сертификатом с сервером . В фоновом режиме реализация SSLServerSocket аутентифицирует клиента с помощью протокола TLS.

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

5. Реализация клиентской Java​

Так же, как и с сервером, клиентская реализация представляет собой простой класс SSLScocketClient :

 public class SSLScocketClient     static void startClient(String host, int port) throws IOException     SocketFactory factory = SSLSocketFactory.getDefault();   try (SSLSocket socket = (SSLSocket) factory.createSocket(host, port))     socket.setEnabledCipherSuites(new String[]  "TLS_AES_128_GCM_SHA256" >);   socket.setEnabledProtocols(new String[]  "TLSv1.3" >);    String message = "Hello World Message";   System.out.println("sending message: " + message);   OutputStream os = new BufferedOutputStream(socket.getOutputStream());   os.write(message.getBytes());   os.flush();    InputStream is = new BufferedInputStream(socket.getInputStream());   byte[] data = new byte[2048];   int len = is.read(data);   System.out.printf("client received %d bytes: %s%n", len, new String(data, 0, len));   >   >   > 

Сначала мы создаем SSLSocket , который устанавливает соединение с сервером. В фоновом режиме сокет установит рукопожатие установления соединения TLS. В рамках этого рукопожатия клиент проверит сертификат сервера и проверит, находится ли он в хранилище доверенных сертификатов клиента .

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

6. Запуск приложений​

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

 java -Djavax.net.ssl.keyStore=/path/to/serverkeystore.p12 \   -Djavax.net.ssl.keyStorePassword=password \  -Djavax.net.ssl.trustStore=/path/to/servertruststore.jks \   -Djavax.net.ssl.trustStorePassword=password \  com.foreach.httpsclientauthentication.SSLSocketEchoServer 

Указываем системные свойства для javax.net.ssl. хранилище ключей и javax.net.ssl. trustStore , чтобы указать на файлы serverkeystore.p12 и servertruststore.jks , которые мы создали ранее с помощью keytool .

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

 java -Djavax.net.ssl.keyStore=/path/to/clientkeystore.p12 \   -Djavax.net.ssl.keyStorePassword=password \   -Djavax.net.ssl.trustStore=/path/to/clienttruststore.jks \   -Djavax.net.ssl.trustStorePassword=password \   com.foreach.httpsclientauthentication.SSLScocketClient 

Точно так же мы устанавливаем javax.net.ssl.keyStore и javax.net.ssl. Системные свойства trustStore , чтобы они указывали на файлы clientkeystore.p12 и clienttruststore.jks , которые мы создали ранее с помощью keytool .

7. Заключение​

Мы написали простую клиент-серверную реализацию Java, которая использует сертификаты сервера и клиента для выполнения двунаправленной аутентификации TLS .

Мы использовали keytool для создания самозаверяющих сертификатов.

Исходный код примеров можно найти на GitHub .

Источник

Saved searches

Use saved searches to filter your results more quickly

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

Simple Java based CLI Tool to test SSL connection and list the ciphers

reflexdemon/java-ssl-test

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Sign In Required

Please sign in to use Codespaces.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching Xcode

If nothing happens, download Xcode and try again.

Launching Visual Studio Code

Your codespace will open once ready.

There was a problem preparing your codespace, please try again.

Latest commit

Git stats

Files

Failed to load latest commit information.

README.md

This is a CLI utility that is used to test the connectivity between your JDK/JRE to an SSL endpoint. This outputs SSL information like the Ciphers, Protocol, prints Certificate details and it is fully customizable using CLI. This is based upon ssltest. Unlike, ssltest, this is multi threaded and is supposed to be 10x times faster to produce results.

GitHub version npm version

Usage: javassltest [opts] host[:port] Options: -sslprotocol Sets the SSL/TLS protocol to be used (e.g. SSL, TLS, SSLv3, TLSv1.2, etc.) -enabledprotocols protocols Sets individual SSL/TLS ptotocols that should be enabled -ciphers cipherspec A comma-separated list of SSL/TLS ciphers -keystore Sets the key store for connections (for TLS client certificates) -keystoretype type Sets the type for the key store -keystorepassword pass Sets the password for the key store -keystoreprovider provider Sets the crypto provider for the key store -truststore Sets the trust store for connections -truststoretype type Sets the type for the trust store -truststorepassword pass Sets the password for the trust store -truststorealgorithm alg Sets the algorithm for the trust store -truststoreprovider provider Sets the crypto provider for the trust store -crlfilename Sets the CRL filename to use for the trust store -check-certificate Checks certificate trust (default: false) -no-check-certificate Ignores certificate errors (default: true) -verify-hostname Verifies certificate hostname (default: false) -no-verify-hostname Ignores hostname mismatches (default: true) -showsslerrors Show SSL/TLS error details -showhandshakeerrors Show SSL/TLS handshake error details -showerrors Show all connection error details -hiderejects Only show protocols/ciphers which were successful -showcerts Shows some basic Certificate details -h -help --help Shows this help message -v -version --version Shows the version information and exists 

To make the distribution seamless, we have used Node Package Manager (NPM) based approach. That will require you to install the application using NPM.

Runs on any platform that supports requirements including Mac, Windows, and Linux.

To install the CLI tool just run the following command.

Troubleshooting on Permissions

If you are running into permission issues on installing global application please refer to this link. https://docs.npmjs.com/getting-started/fixing-npm-permissions

One of the known issue is some of the node versions that do not work and throws errors. In that case please consider the following,

Downgrade the Node Version to the previous stable LTS (Long Term Support) version of nodejs.

  1. Install NVM: https://github.com/creationix/nvm/blob/master/README.md#installation
  2. Install the stable version of nodjs using: nvm install v8.11.1
  3. Install your cli tool: npm i -g

The other issue could be your JDK or JRE are conflicting on the path and that is causing the mixed runtime and Java SSL API is not able to use the correct runtime values.

On linux/unix based systems,

export JAVA_HOME= export PATH=$JAVA_HOME/bin:$PATH 
set JAVA_HOME= set PATH=%JAVA_HOME%\bin;%PATH% 

If the above options did not help and you wish to report issues please visit https://github.com/reflexdemon/java-ssl-test/issues and log your issues with the following details,

  1. java -version output
  2. javac -version output
  3. npm -v output
  4. node -v output

To make this happen I will have to thank the below people and their creations.

Источник

Оцените статью