Подтвердить что ты не робот

Как подключиться к защищенному сайту с использованием 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

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

4b9b3361

Ответ 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
    
  • Импортируйте сертификат ЦС с сервера в TrustStore (ваш собственный или хранилище ключей java в $JAVA_HOME/jre/lib/security/cacerts, пароль: changeit).

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

    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");
    
  • Проверьте ur ur.

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

Ответ 2

Я не могу комментировать из-за 50pts threshhold, но я не думаю, что ответ, представленный в fooobar.com/questions/315546/..., верен. Фактически вы описываете, как вы вставляете сертификаты сервера в хранилище по умолчанию по умолчанию:

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

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

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

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

Ответ 3

Похоже, что вы извлекаете сертификат из хранилища ключей 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 в файл, который не существует; если файл не может быть открыт, создается пустой хранилище ключей, что приведет к этой ошибке.

Ответ 4

Это пример использования ТОЛЬКО файла 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 (Enumeration<String>t=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;i<a.length;i++)
        {
            X509Certificate x509 = (X509Certificate)a[i];
            System.out.println(x509.getSubjectDN().toString());
            if (i>0)
                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);

Ответ 5

В этом примере показано, как вы можете сложить 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();

Ответ 6

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

Шаги: 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, а затем попробуйте. Это действительно решение.:)

Ответ 7

Я понимаю, что эта статья может быть устаревшей, но все же я хотел бы попросить 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 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 );
    }
}

Ответ 8

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;
}