2017-10-11 7 views
0

Je l'ai déjà vu cette question: Need to do a GET&POST HTTPS Request using a .cer certificateUtiliser .cer certificat pour faire une demande HTTPS

mine est tout à fait différent:

Il est possible de faire une demande HTTPS à l'aide de Java (vanille, ou en utilisant tout bibliothèque), approuver un certificat de serveur et fournir un certificat client sans utiliser de fichier de clés, mais en utilisant certificats?

J'ai les deux certificats au format X.509, et je ne veux pas avoir tous les certificats dans un magasin de clés.

+2

aucun problème lors de l'utilisation de java par exemple 'HttpsUrlConnection'. faites juste votre propre 'KeyManager' pour le' SSLContext'. –

+0

@mrmcwolf Pouvez-vous élaborer? Je suis à la recherche de la documentation de KeyManager dès maintenant. – lilezek

+0

@mrmcwolf Suite aux docs Java, j'ai trouvé ceci: https://docs.oracle.com/javase/7/docs/api/javax/net/ssl/X509ExtendedKeyManager.html qui a un constructeur protégé. Y a-t-il une sous-classe que je peux utiliser? – lilezek

Répondre

0

Si vous ne voulez vraiment pas créer un nouveau fichier de magasin de clés, vous pouvez utiliser l'API KeyStore pour créer en mémoire et charger le certificat directement.

InputStream is = new FileInputStream("somecert.cer"); 
// You could get a resource as a stream instead. 

CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
X509Certificate caCert = (X509Certificate)cf.generateCertificate(is); 

TrustManagerFactory tmf = TrustManagerFactory 
    .getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); 
ks.load(null); // You don't need the KeyStore instance to come from a file. 
ks.setCertificateEntry("caCert", caCert); 

tmf.init(ks); 

SSLContext sslContext = SSLContext.getInstance("TLS"); 
sslContext.init(null, tmf.getTrustManagers(), null); 

Sinon, si vous voulez éviter de modifier votre fichier cacerts par défaut, vous devrez implémenter votre propre TrustManager. Cependant, un TrustManager a besoin d'un fichier de clés à charger, ce qui vous permet de créer un nouveau fichier de clés important uniquement votre certificat.

keytool -import -alias ca -file somecert.cer -keystore truststore.jks -storepass changeit 

Et d'utiliser quelque chose comme l'extrait suivant pour charger le fichier keystore.

TrustManagerFactory tmf = TrustManagerFactory 
    .getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
// Using null here initialises the TMF with the default trust store. 
tmf.init((KeyStore) null); 

// Get hold of the default trust manager 
X509TrustManager defaultTm = null; 
for (TrustManager tm : tmf.getTrustManagers()) { 
    if (tm instanceof X509TrustManager) { 
     defaultTm = (X509TrustManager) tm; 
     break; 
    } 
} 

FileInputStream myKeys = new FileInputStream("truststore.jks"); 

// Do the same with your trust store this time 
// Adapt how you load the keystore to your needs 
KeyStore myTrustStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
myTrustStore.load(myKeys, "password".toCharArray()); 

myKeys.close(); 

tmf = TrustManagerFactory 
    .getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
tmf.init(myTrustStore); 

SSLContext sslContext = SSLContext.getInstance("TLS"); 
sslContext.init(null, tmf.getTrustManagers(), null); 
+0

Avez-vous même lu la question ?! –

+0

@ Code.IT après la modification, il a fourni un extrait pour lire directement un certificat X.509. Idk si le downvote est le vôtre, mais je vais upvote cela dès que je testerai la solution. – lilezek

1

Ceci est un exemple approximatif. Représente le décorateur X509KeyManager.

KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
kmf.init(null, null); 

X509KeyManager manager = (X509KeyManager) kmf.getKeyManagers()[0]; 
KeyManager km = new X509KeyManager() { 
    @Override 
    public String[] getClientAliases(String s, Principal[] principals) { 
     return manager.getServerAliases(s, principals); 
    } 

    @Override 
    public String chooseClientAlias(String[] strings, Principal[] principals, Socket socket) { 
     return manager.chooseClientAlias(strings, principals, socket); 
    } 

    @Override 
    public String[] getServerAliases(String s, Principal[] principals) { 
     return manager.getServerAliases(s, principals); 
    } 

    @Override 
    public String chooseServerAlias(String s, Principal[] principals, Socket socket) { 
     return manager.chooseServerAlias(s, principals, socket); 
    } 

    @Override 
    public X509Certificate[] getCertificateChain(String s) { 
     // You can use `s` to select the appropriate file 

     try { 
      File file = new File("path to certificate"); 

      try(InputStream is = new FileInputStream(file)) { 
       CertificateFactory factory = CertificateFactory.getInstance("X.509"); 
       return new X509Certificate[] { 
         (X509Certificate) factory.generateCertificate(is) 
       }; 
      } 
     } 
     catch (CertificateException| IOException e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    @Override 
    public PrivateKey getPrivateKey(String s) { 
     // You can use `s` to select the appropriate file 

     // load and private key from selected certificate 
     // this use for certificate authorisation 

     try { 
      File file = new File("private key file"); 
      byte buffer[] = Files.readAllBytes(file.toPath()); 

      KeySpec keySpec = new PKCS8EncodedKeySpec(buffer); 
      KeyFactory factory = KeyFactory.getInstance("RSA"); 

      return factory.generatePrivate(keySpec); 
     } 
     catch (NoSuchAlgorithmException | IOException | InvalidKeySpecException e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 
}; 

TrustManager tm = new X509TrustManager() { 
    @Override 
    public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { 

    } 

    @Override 
    public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { 

    } 

    @Override 
    public X509Certificate[] getAcceptedIssuers() { 
     try { 
      File file = new File("path to certificate"); 

      try(InputStream is = new FileInputStream(file)) { 
       CertificateFactory factory = CertificateFactory.getInstance("X.509"); 
       return new X509Certificate[] { 
         (X509Certificate) factory.generateCertificate(is) 
       }; 
      } 
     } 
     catch (CertificateException| IOException e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 
}; 

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
tmf.init((KeyStore)null); //use java system trust certificates 

TrustManager managers[] = new TrustManager[tmf.getTrustManagers().length + 1]; 
System.arraycopy(tmf.getTrustManagers(), 0, managers, 0, tmf.getTrustManagers().length); 
managers[managers.length - 1] = tm; 

SSLContext context = SSLContext.getInstance("TLS"); 
context.init(new KeyManager[]{ km }, managers, new SecureRandom()); 

URL url = new URL("https://............/"); 
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); 
connection.setSSLSocketFactory(connection.getSSLSocketFactory()); 

connection.connect();