2016-08-09 61 views
0

Ich muss eine Anwendung mit externen Web-Service integrieren, die zur Verwendung von https zwingt. Autoren dieses Webdienstes haben mir die .crt-Datei zur Verfügung gestellt, die ich für die Erstellung von https-Anfragen verwenden sollte. Nach einigen Untersuchungen habe ich den folgenden Code gefunden, die Keystore-Klasse für gesicherte https-Zugriff verwendet:mit KeyStore mit .crt

 KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
     FileInputStream instream = new FileInputStream(new File(file)); 
     try { 
      trustStore.load(instream, password.toCharArray()); 
     } finally { 
      instream.close(); 
     } 

     SSLContext sslcontext = 
       SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build(); 
     SSLConnectionSocketFactory sslsf = 
       new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1.2"}, null, 
               BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); 
     HttpClients.custom().setSSLSocketFactory(sslsf).build(); 

In diesem Code erfordert Schlüsselspeicher Eingabestrom zusammen mit PassworttrustStore.load(instream, password.toCharArray());. Wie ich jedoch verstehe, brauchen wir kein Passwort, wenn wir die .crt-Datei verwenden. Daher ist diese Art des Ladens von Zertifikaten für mich nicht geeignet. Zur gleichen Zeit, von dem, was ich bisher entdeckt habe, ist der Code, den ich hier zur Verfügung stelle, die einzige Möglichkeit, HttpClient für die Verwendung eines SSL-Zertifikats zu konfigurieren. Gibt es eine Problemumgehung, um HttpClient für die Verwendung von .crt-Zertifikat zu konfigurieren?

Danke,

Andrey

Antwort

1

Ich nehme an, der Web Service, den Sie mit einem selbst signierten Zertifikat bietet (das heißt nicht von einer bekannten Zertifizierungsstelle signiert). Wenn es bereits von einer bekannten Zertifizierungsstelle signiert ist, die sich in der Java-Datei cacerts befindet, müssen Sie nichts tun.

Ansonsten haben Sie ein paar Optionen:

  1. Importieren Sie das Zertifikat in globale cacerts Keys
  2. Ihre Anwendung starten mit anwendungsspezifischen Schlüsselspeicher

In jedem Fall müssen Sie zuerst CRT-Datei in JKS-Keystore konvertieren, die Java verwendet. Sie können dies tun, indem sie:

$ keytool -import -keystore mykeystore.jks -storepass horsestaple 

Beachten Sie, dass keytool das Passwort (horsestaple oben) erfordert für die Schaffung eines JKS Speicher geliefert werden. Du kannst dort alles hinstellen; Wie Sie erwähnen, benötigen öffentliche Website-Zertifikate keinen Passwortschutz, sie sind schließlich öffentlich.

Wenn Sie Option 1 ausführen, erstellen Sie eine Sicherungskopie Ihrer Cacerts und stellen Sie die Datei cacerts statt mykeyStore.jks bereit. Sehen Sie den folgenden Link für den Standort von Cacerts. Für diese Option sind Sie bereit, Ihre Anwendung sollte ohne zusätzliche Konfiguration eine Verbindung zum Webdienst über HTTPS herstellen, da Java standardmäßig CACERTs lädt.

Wenn Sie tun, Option 2, die wahrscheinlich zumindest für Testphase bevorzugt wird, müssen Sie Ihre Anwendung mit diesem Parameter ausführen:

-Djavax.net.ssl.trustStore=mykeystore.jks 

Dies ist eine JVM-Parameter ist, so dass es in geeigneter Weise zuzuführen. Dies hängt davon ab, wie Sie Ihre Anwendung ausführen.

Beachten Sie, dass Sie in diesem Fall nur das importierte Zertifikat haben, damit Ihre anderen HTTPS-Verbindungen nicht funktionieren. Sie können dies vermeiden, indem Sie zuerst die Standardcacerts in einen temporären Speicherort kopieren, den Schlüssel darin importieren und den Befehl oben verwenden. Damit erhalten Sie alle Standardzertifikate und das, das Sie benötigen.

Ein kleiner Nachteil von Option 2 ist, dass beim Hinzufügen oder Widerrufen neuer Zertifikate der anwendungsspezifische Schlüsselspeicher nicht aktualisiert wird.Wenn dies ein Problem ist, können Sie Schlüsselspeicher im laufenden Betrieb, zum Beispiel verschmelzen:

In jedem Fall sollten Sie jetzt in der Lage sein zu tun, nur eine Standard-URL zu holen, wie in Beispiel hier gegeben:

dh:

012.351.
final URL url = new URL("https://example.com"); 
try(final InputStream in = url.openStream()){ 
    //… 
} 

Weitere Informationen hier:

  • Keytool und allgemeine Zertifikate info

https://docs.oracle.com/cd/E19830-01/819-4712/ablqw/index.html

  • CACERTS Lage

http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/keytool.html

  • Weitere Optionen für den Import von selbstsignierten Zertifikaten

How to properly import a selfsigned certificate into Java keystore that is available to all Java applications by default?

Hoffnung, das hilft.

+0

Eine dritte Option besteht darin, den Truststore direkt mit der Client-API zu verwenden, was das OP so aussehen lässt. Dies ist besser als jede der beiden Optionen, die Sie ursprünglich vorgestellt haben, da es keine andere Verwendung von Trust Stores beeinträchtigt. –

+0

@ChristopherSchultz Einverstanden, wenn OP die ursprüngliche Lösung verwenden will, sicher, sicher kann. Ich denke, es hängt vom Anwendungsfall ab, dass es bei einer Verteilung auf mehrere Anwendungen einfacher sein könnte, globale Cacerts zu aktualisieren. –

0

Es sei denn, sie zur Verfügung gestellt Sie mit ihre .crt-Datei, die für die Validierung Verbindungen - sie verwendet werden sollten, die sie verwenden ein selbst signiertes Zertifikat anzeigen würde, haben sie Sie nicht mit etwas versehen nützlich . Wenn Sie benötigen ein Zertifikat als Client, das erste, was Sie brauchen, ist ein öffentliches/privates Schlüsselpaar, aus dem Sie eine CSR generieren, die Sie signiert bekommen. Niemand außer dem signierten Zertifikat kann dies sicher gewährleisten.

Wenn sie ihr eigenes (selbstsignierten?) Zur Verfügung gestellt hat Zertifikat, müssen Sie es in ein -Vertrauen laden, kein Schlüsselspeicher, über die keytool mit der -trustcacerts Option, und dann Java sagen, dass truststore verwenden entweder über die Systemeigenschaft javax.net.ssl.trustStore oder indem Sie Ihre eigene TrustManager erstellen und sie an eine benutzerdefinierte SSLContext, wie im JSSE-Referenzhandbuch beschrieben, übergeben.