Как подключиться к защищенному сайту с использованием SSL в Java с файлом pkcs12?

У меня есть файл pkcs12. Мне нужно использовать это для подключения к веб-странице с использованием протокола https. Я натолкнулся на какой-то код, где для подключения к безопасной веб-странице мне нужно установить следующие системные свойства:

System.setProperty("javax.net.ssl.trustStore", "myTrustStore"); System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); System.setProperty("javax.net.ssl.keyStoreType", "pkcs12"); System.setProperty("javax.net.ssl.keyStore", "new_cert.p12"); System.setProperty("javax.net.ssl.keyStorePassword", "newpass"); 

У меня есть файл p12 (pkcs12). Все, что мне нужно, это файл доверия.

Я извлек сертификаты, используя:

 openssl.exe pkcs12 -in c:/mykey.p12 -out c:/cert.txt -nokeys -clcerts 

Теперь преобразованный файл PEM сертификата в der

 openssl.exe x509 -in c:/cert.txt -outform DER -out c:/CAcert.der 

Теперь добавив файл der в хранилище ключей

 keytool -import -file C:/Cacert.der -keystore mytruststore 

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

 Exception in thread "main" java.net.SocketException: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl) 

Обновление. После удаления определенных свойств и установки только свойств «trustStore», «trustStorePassword» и «trustStoreType» я получил следующее исключение

 java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty 

Пожалуйста помоги.

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

  1. Восстановите файл pkcs12 следующим образом:

     openssl pkcs12 -in oldpkcs.p12 -out keys -passout pass:tmp openssl pkcs12 -in keys -export -out new.p12 -passin pass:tmp -passout pass:newpasswd 
  2. Импортируйте сертификат ЦС с сервера в TrustStore (ваш собственный или хранилище java в $JAVA_HOME/jre/lib/security/cacerts , password: changeit ).

  3. Задайте следующие системные свойства:

     System.setProperty("javax.net.ssl.trustStore", "myTrustStore"); System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); System.setProperty("javax.net.ssl.keyStoreType", "pkcs12"); System.setProperty("javax.net.ssl.keyStore", "new.p12"); System.setProperty("javax.net.ssl.keyStorePassword", "newpasswd"); 
  4. Проверьте ur ur.

Courtesy @ http://forums.sun.com/thread.jspa?threadID=5296333

Я не могу прокомментировать из-за 50pts threshhold, но я не думаю, что ответ, указанный в https://stackoverflow.com/a/537344/1341220 , верен. Фактически вы описываете, как вы вставляете сертификаты сервера в сеть доверия по умолчанию:

 $JAVA_HOME/jre/lib/security/cacerts, password: changeit) 

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

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

 System.setProperty("javax.net.ssl.trustStore", "myTrustStore"); System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); 

Похоже, что вы извлекаете сертификат из хранилища ключей PKCS # 12 и создаете новое хранилище ключей Java (с типом «JKS»). Вам не обязательно предоставлять пароль хранилища доверия (хотя использование одного позволяет вам проверить целостность ваших корневых сертификатов).

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

 System.setProperty("javax.net.ssl.trustStore", "myTrustStore"); System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); 

Кроме того, использование файла PKCS # 12 непосредственно в качестве хранилища доверия должно работать, если сертификат ЦС определяется как «доверенная» запись. Но в этом случае вам нужно будет указать свойство javax.net.ssl.trustStoreType как "PKCS12" .

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


Новая ошибка: «параметр trustAnchors должен быть непустым», может быть связано с установкой свойства javax.net.ssl.trustStore файлу, который не существует; если файл не может быть открыт, создается пустой хранилище ключей, что приведет к этой ошибке.

Это пример использования ТОЛЬКО файла p12, который он не оптимизирован, но он работает. Файл pkcs12, который генерируется OpenSSL мной. Пример того, как загрузить файл p12 и создать из него зону доверия … Он выводит сертификаты из файла p12 и добавляет хорошие сертификаты в TrustStore

 KeyStore ks=KeyStore.getInstance("pkcs12"); ks.load(new FileInputStream("client_t_c1.p12"),"c1".toCharArray()); KeyStore jks=KeyStore.getInstance("JKS"); jks.load(null); for (Enumerationt=ks.aliases();t.hasMoreElements();) { String alias = t.nextElement(); System.out.println("@:" + alias); if (ks.isKeyEntry(alias)){ Certificate[] a = ks.getCertificateChain(alias); for (int i=0;i0) jks.setCertificateEntry(x509.getSubjectDN().toString(), x509); System.out.println(ks.getCertificateAlias(x509)); System.out.println("ok"); } } } System.out.println("init Stores..."); KeyManagerFactory kmf=KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, "c1".toCharArray()); TrustManagerFactory tmf=TrustManagerFactory.getInstance("SunX509"); tmf.init(jks); SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 

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

По сути, однако, как только у вас есть контекст SSL, вы можете применить его к HttpsURLConnection и т. Д. И т. Д.

 KeyStore ks = KeyStore.getInstance("PKCS12"); InputStream is = ...; char[] ksp = storePassword.toCharArray(); ks.load(is, ksp); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); char[] kp = keyPassword.toCharArray(); kmf.init(ks, kp); sslContext = SSLContext.getInstance("SSLv3"); sslContext.init(kmf.getKeyManagers(), null, null); SSLSocketFactory factory = sslContext.getSocketFactory(); SSLSocket sslsocket = (SSLSocket) factory.createSocket(socket, socket .getInetAddress().getHostName(), socket.getPort(), true); sslsocket.setUseClientMode(true); sslsocket.setSoTimeout(soTimeout); sslsocket.startHandshake(); 
 URL url = new URL("https://test.domain:443"); String keyStore = "server.p12" String keyStorePassword = "changeit"; String keyPassword = "changeit"; String KeyStoreType= "PKCS12"; String KeyManagerAlgorithm = "SunX509"; String SSLVersion = "SSLv3"; public HttpURLConnection getHttpsURLConnection(URL url, String keystore, String keyStorePass,String keyPassword, String KeyStoreType ,String KeyManagerAlgorithm, String SSLVersion) throws NoSuchAlgorithmException, KeyStoreException, CertificateException, FileNotFoundException, IOException, UnrecoverableKeyException, KeyManagementException { System.setProperty("javax.net.debug","ssl,handshake,record"); SSLContext sslcontext = SSLContext.getInstance(SSLVersion); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerAlgorithm); KeyStore ks = KeyStore.getInstance(KeyStoreType); ks.load(new FileInputStream(keystore), keyStorePass.toCharArray()); kmf.init(ks, keyPassword.toCharArray()); TrustManagerFactory tmf = TrustManagerFactory .getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(ks); TrustManager[] tm = tmf.getTrustManagers(); sslcontext.init(kmf.getKeyManagers(), tm, null); SSLSocketFactory sslSocketFactory = sslcontext.getSocketFactory(); HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory); HttpsURLConnection httpsURLConnection = ( HttpsURLConnection)uRL.openConnection(); return httpsURLConnection; } 

Следующие шаги помогут вам решить проблему.

Шаги: developer_identity.cer <= скачать с Apple mykey.p12 <= Ваш закрытый ключ

Команды:

  openssl x509 -in developer_identity.cer -inform DER -out developer_identity.pem -outform PEM openssl pkcs12 -nocerts -in mykey.p12 -out mykey.pem openssl pkcs12 -export -inkey mykey.pem -in developer_identity.pem -out iphone_dev.p12 

Окончательный p12, который нам потребуется, – файл iphone_dev.p12 и кодовая фраза.

используйте этот файл как ваш p12, а затем попробуйте. Это действительно решение. 🙂

Я понимаю, что эта статья может быть устаревшей, но все же я хотел бы попросить smithsv исправить его исходный код, он содержит много ошибок, мне удалось исправить большинство из них, но до сих пор не знаю, какой именно объект x509 может быть. исходный код, как мне кажется, должен быть:

 import java.io.FileInputStream; import java.security.KeyStore; import java.security.cert.Certificate; import java.util.Enumeration; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; public class Connection2 { public void connect() { /* * This is an example to use ONLY p12 file it's not optimazed but it * work. The pkcs12 file where generated by OpenSSL by me. Example how * to load p12 file and build Trust zone from it... It outputs * certificates from p12 file and add good certs to TrustStore */ KeyStore ks = KeyStore.getInstance( "pkcs12" ); ks.load( new FileInputStream( cert.pfx ), "passwrd".toCharArray() ); KeyStore jks = KeyStore.getInstance( "JKS" ); jks.load( null ); for( Enumeration t = ks.aliases(); t.hasMoreElements(); ) { String alias = (String )t.nextElement(); System.out.println( "@:" + alias ); if( ks.isKeyEntry( alias ) ) { Certificate[] a = ks.getCertificateChain( alias ); for( int i = 0; i == 0; ) jks.setCertificateEntry( x509Cert.getSubjectDN().toString(), x509 ); System.out.println( ks.getCertificateAlias( x509 ) ); System.out.println( "ok" ); } } System.out.println( "init Stores..." ); KeyManagerFactory kmf = KeyManagerFactory.getInstance( "SunX509" ); kmf.init( ks, "c1".toCharArray() ); TrustManagerFactory tmf = TrustManagerFactory.getInstance( "SunX509" ); tmf.init( jks ); SSLContext ctx = SSLContext.getInstance( "TLS" ); ctx.init( kmf.getKeyManagers(), tmf.getTrustManagers(), null ); } } 
  • Как создать самозаверяющий сертификат с openssl?
  • Как использовать ssh / scp между непубличными машинами
  • Принять самоподписанный сертификат ssl сервера в Java-клиенте
  • «Проверьте ошибку: num = 20» при подключении к gateway.sandbox.push.apple.com
  • Как мне сделать TLS с BouncyCastle?
  • java - игнорировать сертификат ssl
  • Страницы SSL в ASP.NET MVC
  • прием HTTPS-соединений с самозаверяющими сертификатами
  • Как включить SSL 3 в Java
  • javax.net.ssl.SSLException: Получено фатальное предупреждение: protocol_version
  • Заставить браузер загружать «https» версию веб-сайта, а не «http»?
  • Давайте будем гением компьютера.