Создание сокета SSL с использованием импортированного сертификата без закрытого ключа ⇐ JAVA
-
Anonymous
Создание сокета SSL с использованием импортированного сертификата без закрытого ключа
Я новичок в SSL и, честно говоря, нашел реализацию довольно запутанной, поэтому извините, если мой вопрос покажется невежественным или необоснованным.
Итак, у меня есть сервер сокетов SSL, использующий самозаверяющий сертификат в виде файла p12. Я хочу, чтобы клиентский сокет мог подключаться к этому серверу БЕЗ доступа к закрытому ключу. Однако я хочу, чтобы клиент мог убедиться, что сервер не является самозванцем и имеет закрытый ключ.
Моя проблема в том, что я не могу создать SSLContext и, следовательно, SSLSocketFactory, используя что-либо, кроме файла p12. В идеале я бы создал SSLSocketFactory, используя корневой файл сертификата.
Вот как я настроил свой клиент:
публичный класс SSLClient { частная статическая финальная строка TLS_VERSION = "TLSv1.2"; public static void run(int serverPort, String certName, char[] certPass) выдает исключение { KeyStoretrustStore = KeyStore.getInstance(KeyStore.getDefaultType()); InputStream certInputStream = TLSClient.class.getResourceAsStream("/" + certName); TrustStore.load(certInputStream, certPass); certInputStream.close(); TrustManagerFactorytrustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); TrustManagerFactory.init(trustStore); KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); InputStream keyStoreInputStream = TLSClient.class.getResourceAsStream("/" + certName); keyStore.load(keyStoreInputStream, certPass); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keyStore, certPass); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(keyManagerFactory.getKeyManagers(),trustManagerFactory.getTrustManagers(), SecureRandom.getInstanceStrong()); Фабрика SocketFactory = sslContext.getSocketFactory(); попробуйте (Socket Connection = Factory.createSocket("localhost", serverPort)) { ((SSLSocket) соединение).setEnabledProtocols(new String[] {TLS_VERSION}); SSLParameters sslParams = новые SSLParameters(); sslParams.setEndpointIdentificationAlgorithm("HTTPS"); ((SSLSocket) соединение).setSSLParameters(sslParams); Вход BufferedReader = новый BufferedReader (новый InputStreamReader (connection.getInputStream ())); System.out.println(input.readLine()); новый PrintWriter(connection.getOutputStream(),true).println("ответ клиента"); } } } Я пробовал использовать корневой сертификат (.crt) и файл PEM, но оба они выдают ошибку входного потока:
Исключение в потоке «main» java.io.IOException: toDerInputStream отклоняет тип тега 45 в java.base/sun.security.util.DerValue.toDerInputStream(DerValue.java:1155) по адресу java.base/sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:2013) в java.base/sun.security.util.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:221) в java.base/java.security.KeyStore.load(KeyStore.java:1473) в TLSClient.run(TLSClient.java:16) в Main.main(Main.java:12) Мой текущий подход/решение: я создал «пустой» файл p12 для клиента, используя корневой сертификат сервера. Кажется, это работает так, как задумано... есть ли проблемы при таком подходе?
сделано с использованием:
openssl pkcs12 -export -in myCert.crt -out myCertPks.p12 -name псевдоним
Я новичок в SSL и, честно говоря, нашел реализацию довольно запутанной, поэтому извините, если мой вопрос покажется невежественным или необоснованным.
Итак, у меня есть сервер сокетов SSL, использующий самозаверяющий сертификат в виде файла p12. Я хочу, чтобы клиентский сокет мог подключаться к этому серверу БЕЗ доступа к закрытому ключу. Однако я хочу, чтобы клиент мог убедиться, что сервер не является самозванцем и имеет закрытый ключ.
Моя проблема в том, что я не могу создать SSLContext и, следовательно, SSLSocketFactory, используя что-либо, кроме файла p12. В идеале я бы создал SSLSocketFactory, используя корневой файл сертификата.
Вот как я настроил свой клиент:
публичный класс SSLClient { частная статическая финальная строка TLS_VERSION = "TLSv1.2"; public static void run(int serverPort, String certName, char[] certPass) выдает исключение { KeyStoretrustStore = KeyStore.getInstance(KeyStore.getDefaultType()); InputStream certInputStream = TLSClient.class.getResourceAsStream("/" + certName); TrustStore.load(certInputStream, certPass); certInputStream.close(); TrustManagerFactorytrustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); TrustManagerFactory.init(trustStore); KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); InputStream keyStoreInputStream = TLSClient.class.getResourceAsStream("/" + certName); keyStore.load(keyStoreInputStream, certPass); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keyStore, certPass); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(keyManagerFactory.getKeyManagers(),trustManagerFactory.getTrustManagers(), SecureRandom.getInstanceStrong()); Фабрика SocketFactory = sslContext.getSocketFactory(); попробуйте (Socket Connection = Factory.createSocket("localhost", serverPort)) { ((SSLSocket) соединение).setEnabledProtocols(new String[] {TLS_VERSION}); SSLParameters sslParams = новые SSLParameters(); sslParams.setEndpointIdentificationAlgorithm("HTTPS"); ((SSLSocket) соединение).setSSLParameters(sslParams); Вход BufferedReader = новый BufferedReader (новый InputStreamReader (connection.getInputStream ())); System.out.println(input.readLine()); новый PrintWriter(connection.getOutputStream(),true).println("ответ клиента"); } } } Я пробовал использовать корневой сертификат (.crt) и файл PEM, но оба они выдают ошибку входного потока:
Исключение в потоке «main» java.io.IOException: toDerInputStream отклоняет тип тега 45 в java.base/sun.security.util.DerValue.toDerInputStream(DerValue.java:1155) по адресу java.base/sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:2013) в java.base/sun.security.util.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:221) в java.base/java.security.KeyStore.load(KeyStore.java:1473) в TLSClient.run(TLSClient.java:16) в Main.main(Main.java:12) Мой текущий подход/решение: я создал «пустой» файл p12 для клиента, используя корневой сертификат сервера. Кажется, это работает так, как задумано... есть ли проблемы при таком подходе?
сделано с использованием:
openssl pkcs12 -export -in myCert.crt -out myCertPks.p12 -name псевдоним
Мобильная версия