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.
8 réponses
pour toute personne se trouvant dans une situation semblable, j'ai pu résoudre le problème ci-dessus comme suit:
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
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
).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");
test ur URL.
courtoisie@ http://forums.sun.com/thread.jspa?threadID=5296333
$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");
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.
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);
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();
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;
}
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.:)
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 );
}
}