Comment se connecter à un site Web sécurisé en utilisant SSL en Java avec un fichier pkcs12?

j'ai un fichier pkcs12. Je dois utiliser ceci pour me connecter à une page Web en utilisant le protocole https. Je suis tombé sur un certain code pour se connecter à une page web sécurisée j'ai besoin de configurer les propriétés système suivantes:

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");

j'ai le fichier P12(pkcs12). Tout ce dont j'ai besoin, c'est d'un fichier de confiance.

j'ai extrait les certificats en utilisant:

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

maintenant converti le fichier cert PEM en der

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

ajouter maintenant le fichier der à un keystore

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

Maintenant, j'ai le truststore, mais quand je l'utilise, j'obtiens l'erreur suivante

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)

mise à jour: Après avoir supprimé certaines propriétés et réglé seulement la propriété" trustStore"," trustStorePassword "et" trustStoreType", j'ai obtenu l'exception suivante

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

S'Il Vous Plaît Aider.

18
demandé sur user27221 2009-02-11 17:32:29

8 réponses

pour toute personne se trouvant dans une situation semblable, j'ai pu résoudre le problème ci-dessus comme suit:

  1. Régénérer votre fichier pkcs12 comme suit:

    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. importez le certificat CA du serveur dans une librairie (soit la vôtre, soit le Java keystore dans $JAVA_HOME/jre/lib/security/cacerts, mot de passe: changeit).

  3. définir les propriétés suivantes du système:

    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. test ur URL.

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

20
répondu user27221 2009-10-18 21:08:34
https://stackoverflow.com/a/537344/1341220 is correct. Ce que vous décrivez en fait est la façon dont vous insérez des certificats de serveur dans le système par défaut truststststore:

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

Cela fonctionne, en effet, mais cela signifie que vous n'avez pas vraiment préciser un magasin de confiance local à votre projet, mais plutôt accepté le certificat universially dans votre système.

Vous en fait, n'utilisez jamais votre propre boutique que vous avez définie ici:

System.setProperty("javax.net.ssl.trustStore", "myTrustStore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
5
répondu Steffi 2017-05-23 12:09:30

il semble que vous extrayez votre certificat du magasin de clés PKCS #12 et que vous créez un nouveau magasin de clés Java (avec le type "JKS"). Vous n'êtes pas strictement tenu de fournir un mot de passe trust store (bien que l'utilisation d'un tel mot de passe vous permette de tester l'intégrité de vos certificats racine).

alors, essayez votre programme avec les propriétés SSL suivantes sont définies. La liste affichée dans votre question est trop précise et peut causer des problèmes.

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

aussi, en utilisant le fichier PKCS #12 directement sous la forme du magasin de confiance devrait fonctionner, à condition que le certificat de L'AC soit détecté comme une entrée "de confiance". Mais dans ce cas, vous devrez spécifier les javax.net.ssl.trustStoreType propriété "PKCS12" trop.

Essayez avec ces propriétés. Si vous avez la même erreur, je soupçonne que votre problème n'est pas le magasin de clés. Si cela se produit, afficher plus de la trace de la pile dans votre question, pour limiter le problème.


la nouvelle erreur, " le paramètre trustAnchors doit être non vide, " peut être dû à la mise en place du javax.net.ssl.trustStore propriété d'un fichier qui n'existe pas; si le fichier ne peut pas être ouvert, un magasin de clés vide a été créé, ce qui conduirait à cette erreur.

4
répondu erickson 2009-02-13 05:26:44

ceci est un exemple pour utiliser seulement le fichier p12 il n'est pas optimisé mais il fonctionne. Le fichier pkcs12 a été généré par OpenSSL par moi. Exemple comment charger le fichier p12 et construire la zone de confiance à partir de celui-ci... Il produit des certificats à partir du fichier p12 et ajoute de bons certs à Trustststore

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);
4
répondu user122678 2010-01-10 16:06:03

cet exemple montre comment vous pouvez calquer SSL sur une socket existante, en obtenant le client cert à partir d'un fichier PKCS#12. Il est approprié lorsque vous avez besoin de vous connecter à un serveur amont via un proxy, et que vous voulez gérer vous-même le protocole complet.

essentiellement, cependant, une fois que vous avez le contexte SSL, vous pouvez l'appliquer à une connexion HttpsURLConnection, etc, etc.

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();
1
répondu Rogan Dawes 2009-11-19 07:19:43
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;
}
1
répondu Mohamad Faisal 2013-03-03 09:11:30

les étapes suivantes vous aideront à régler votre problème.

les Étapes: developer_identity.cer <= de téléchargement d'Apple maclé.p12 <= Votre clé privée

commandes à suivre:

    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

Final p12 dont nous aurons besoin est iphone_dev.fichier p12 et le mot de passe.

Utilisez ce fichier comme votre p12 puis essayez. C'est effectivement la solution.:)

1
répondu Apurv Nerlekar 2013-07-08 11:37:42

je me rends compte que cet article peut être dépassé mais je voudrais quand même demander à smithsv de corriger son code source, il contient beaucoup d'erreurs, j'ai réussi à corriger la plupart d'entre eux mais je ne sais toujours pas quel type d'objet x509 pourrait être.Voici le code source tel que je pense qu'il devrait être:

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 );
    }
}
0
répondu Roquen 2010-01-10 16:04:55