it-swarm.com.de

Java- und SSL-Zertifikate

Ich versuche, eine Verbindung mit einem PHP-Skript von mir in Java mithilfe der sicheren Socket-Schicht (HTTPS) herzustellen, aber ich habe herausgefunden, dass ich das SSL-Zertifikat importieren muss, um maximale Sicherheit/Gültigkeit zu gewährleisten Meine Website verwendet in meiner Anwendung ... Etwas, was ich nicht wissen kann.

Wenn es hilft, ist mein SSL-Zertifikat nicht selbstsigniert, sondern wird von StartSSL bereitgestellt. UND ich verwende Eclipse IDE.

Könnte mich jemand in die richtige Richtung weisen? Welche Dateien benötige ich, wo muss ich sie importieren und welchen Code benötige ich in Java usw.?

10
Andy

Ich habe herausgefunden, dass ich zur Sicherstellung der maximalen Sicherheit/Gültigkeit das von meiner Website verwendete SSL-Zertifikat in meine Anwendung importieren muss

Sie haben teilweise Recht, wenn Sie diese Aussage machen. Sie müssen Ihr SSL-Zertifikat nicht importieren. Es reicht aus, das StartSSL CA-Zertifikat zu importieren.

Außerdem gibt es kein Importieren eines Zertifikats in eine Java-Anwendung. Die SSL-Unterstützung in Java basiert auf dem Konzept von Keystores und Truststores und nicht auf einem in Ihrer Anwendung enthaltenen Zertifikat. Wenn Sie Ihre Anwendung veröffentlichen, um von Endbenutzern heruntergeladen und ausgeführt zu werden, besteht keine Notwendigkeit, dass Sie Ihr Zertifikat oder Ihren privaten Schlüssel in Ihrer Anwendung veröffentlichen. Der private Schlüssel und das zugehörige Zertifikat würden in einem Schlüsselspeicher gespeichert, auf den nur Sie zugreifen können.

Die Endbenutzer Ihrer Anwendung würden sich innerhalb der Java-Laufzeitumgebung auf die SSL-Unterstützung verlassen, sodass die Anwendung nach der Überprüfung des Serverzertifikats SSL-Verbindungen zu Sites herstellen kann. Die Java-Laufzeitumgebung wird mit einem Standardsatz von CA-Zertifikaten in einem Truststore geliefert. Die einzige Voraussetzung für den erfolgreichen Aufbau von SSL-Verbindungen ist, dass das SSL-Zertifikat des Servers von einer der CAs im Truststore ausgestellt wird.Die Zertifikate von StartSSL sind nicht im Truststore der Java-Laufzeitumgebung vorhanden, mindestens ab Version 6, und daher:

  • Sie können Ihre Endbenutzer anweisen, die Aktivität des Imports des Zertifikats StartSSL CA in den Java Truststore auszuführen. Zu den Links, die hilfreich sein können, gehören dieses StartSSL-Forumsthread (nur die ersten 4 Schritte sind erforderlich, um die Zertifizierungsstellenzertifikate in einen Truststore zu importieren), ein GitHub-Projekt und dieser Blogbeitrag ; Haftungsausschluss - Ich habe nicht versucht, eine davon zu verwenden, und Sie sollten sie auf eigenes Risiko verwenden.
  • Sie können Ihre Anwendung auch mit Ihrem eigenen Truststore unter Verwendung der JVM-Startflags -Djavax.net.ssl.trustStore=<path_to_truststore> -Djavax.net.ssl.trustStorePassword=<truststore_password> initialisieren oder den folgenden Code ausführen, bevor Sie SSL-Verbindungen initialisieren:

    System.setProperty("javax.net.ssl.trustStore","<path_to_truststore>");
    System.setProperty("javax.net.ssl.trustStorePassword","<truststore_password>");
    

    Dies ist nur dann ein gangbarer Ansatz, wenn es sich bei Ihrer Anwendung um eine Java SE-Anwendung handelt, bei der es sich nicht um ein Applet handelt (oder um eine Anwendung mit ähnlichen Einschränkungen für die Angabe des Truststores).


Es würde auch helfen, die Dokumentation des Java-Keytools zu lesen .

26
Vineet Reynolds

Offensichtlich wollen die Mailgun-Ingenieure aus irgendeinem Grund keine klaren Anweisungen zur Lösung dieses Problems geben. Das habe ich getan 

Wir betreiben Tomcat8 und stellen über Jersey-Webservices eine Verbindung zur Mailgun-API her. Ich habe die Benutzeranweisungen befolgt und es hat gut funktioniert. Hoffe das hilft jemandem.

Am 1/22 haben wir unsere SSL-Zertifikate aufgrund der nicht vertrauenswürdigen PKI-Infrastruktur von Symantec aktualisiert. Einige ältere Java-Versionen verfügen nicht über die Zertifizierungsstelle "DigiCert Global Root G2".

Es gibt mehrere Möglichkeiten:

Importieren Sie die CA "DigiCert Global Root G2" in Ihre "cacerts" -Datei. Aktualisieren Sie Ihre JRE auf 8u91 (oder höher), die diesen Stamm enthält. So importieren Sie den "DigiCert Global Root G2" Sie können das Stammverzeichnis von https://www.digicert.com/digicert-root-certificates.htm herunterladen. Stellen Sie sicher, dass Sie das richtige Stammzertifikat herunterladen.

Nachdem das Zertifikat heruntergeladen wurde, müssen Sie es mit einem Befehl wie dem folgenden importieren:

keytool -import -trustcacerts -keystore/path/to/cacerts -storepass change -noprompt -alias digicert-global-root-g2 -file /path/to/digicert.crt[.____.(Sie müssen den Pfad auf setzen Ihren Java-Keystore und den Speicherort des heruntergeladenen Stammzertifikats.


Also 1. /path/to/digicert.crt ist die gerade heruntergeladene Datei. 2./path/to/cacerts - Dies ist in Ihrem JRE-Pfad. Wenn Sie "/ -name cacerts -print" finden, können Sie schnell alle Java-Zertifikate in Ihrem Dateisystem finden. Für mich waren es/usr/lib/jvm/Java-7-openjdk-AMD64/jre/lib/security/cacerts 

2
Will Berger

Die folgende Methode lädt den Standardschlüsselspeicher (cacerts), prüft, ob ein Zertifikat installiert ist, und installiert es, falls nicht. Dadurch entfällt die Notwendigkeit, den Befehl keystore auf Servern manuell auszuführen.

Es wird davon ausgegangen, dass das Standardkennwort für den Keystore (changeit) unverändert bleibt. Wenn nicht, aktualisieren Sie CACERTS_PASSWORD. Beachten Sie, dass die Methode den Schlüsselspeicher nach dem Hinzufügen eines Zertifikats speichert. Nach der Ausführung wird das Zertifikat dann dauerhaft im Speicher gespeichert.

import Java.io.File;
import Java.io.FileInputStream;
import Java.io.FileNotFoundException;
import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.io.InputStream;
import Java.net.MalformedURLException;
import Java.net.URL;
import Java.security.KeyStore;
import Java.security.KeyStoreException;
import Java.security.NoSuchAlgorithmException;
import Java.security.cert.Certificate;
import Java.security.cert.CertificateException;
import Java.security.cert.CertificateFactory;

/**
 * Add a certificate to the cacerts keystore if it's not already included
 */
public class SslUtil {
    private static final String CACERTS_PATH = "/lib/security/cacerts";

    // NOTE: DO NOT STORE PASSWORDS IN PLAIN TEXT CODE, LOAD AT RUNTIME FROM A SECURE CONFIG
    // DEFAULT CACERTS PASSWORD IS PROVIDED HERE AS A QUICK, NOT-FOR-PRODUCTION WORKING EXAMPLE
    // ALSO, CHANGE THE DEFAULT CACERTS PASSWORD, AS IT IMPLORES YOU TO!
    private static final String CACERTS_PASSWORD = "changeit";

    /**
     * Add a certificate to the cacerts keystore if it's not already included
     * 
     * @param alias The alias for the certificate, if added
     * @param certInputStream The certificate input stream
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws CertificateException
     * @throws IOException
     */
    public static void ensureSslCertIsInKeystore(String alias, InputStream certInputStream)
            throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException{
        //get default cacerts file
        final File cacertsFile = new File(System.getProperty("Java.home") + CACERTS_PATH);
        if (!cacertsFile.exists()) {
            throw new FileNotFoundException(cacertsFile.getAbsolutePath());
        }

        //load cacerts keystore
        FileInputStream cacertsIs = new FileInputStream(cacertsFile);
        final KeyStore cacerts = KeyStore.getInstance(KeyStore.getDefaultType());
        cacerts.load(cacertsIs, CACERTS_PASSWORD.toCharArray());
        cacertsIs.close();

        //load certificate from input stream
        final CertificateFactory cf = CertificateFactory.getInstance("X.509");
        final Certificate cert = cf.generateCertificate(certInputStream);
        certInputStream.close();

        //check if cacerts contains the certificate
        if (cacerts.getCertificateAlias(cert) == null) {
            //cacerts doesn't contain the certificate, add it
            cacerts.setCertificateEntry(alias, cert);
            //write the updated cacerts keystore
            FileOutputStream cacertsOs = new FileOutputStream(cacertsFile);
            cacerts.store(cacertsOs, CACERTS_PASSWORD.toCharArray());
            cacertsOs.close();
        }
    }
}

Verwenden Sie es wie folgt:

SslUtil.ensureSslCertIsInKeystore("startssl", new FileInputStream("/path/to/cert.crt"));
1
Shane

Ich habe herausgefunden, dass ich das SSL-Zertifikat importieren muss, um maximale Sicherheit/Gültigkeit zu gewährleisten

Nein, das tust du nicht. Sie benötigen diesen Schritt nur, wenn Ihre Clients dem Unterzeichner des Serverzertifikats nicht bereits vertrauen. Dies tritt nur auf, wenn das Serverzertifikat selbstsigniert oder signiert ist, z. von einer internen Zertifizierungsstelle.

0
user207421

Schauen Sie sich den folgenden Artikel an: http://stilius.net/Java/java_ssl.php Er enthält Codebeispiele, die hilfreich sein können, wenn Sie versuchen, über Code auf Ihr Skript zuzugreifen.

Beachten Sie, dass Sie entweder Systemeigenschaften verwenden sollten

javax.net.ssl.keyStore
javax.net.ssl.keyStorePassword

um das SSL-Zertifikat an JVM zu übergeben, oder importieren Sie es mit keytool tool in den JRE-Keystore

0
Sergey