Wie behebt man den Fehler „java.security.cert.CertificateException: Keine alternativen Antragstellernamen vorhanden“?

Lesezeit: 10 Minuten

Wie behebt man den Fehler „javasecuritycertCertificateException Keine alternativen Antragstellernamen vorhanden
Dmitrij Pisarenko

Ich habe einen Java-Webservice-Client, der einen Webservice über HTTPS nutzt.

import javax.xml.ws.Service;

@WebServiceClient(name = "ISomeService", targetNamespace = "http://tempuri.org/", wsdlLocation = "...")
public class ISomeService
    extends Service
{

    public ISomeService() {
        super(__getWsdlLocation(), ISOMESERVICE_QNAME);
    }

Wenn ich eine Verbindung zur Dienst-URL (https://AAA.BBB.CCC.DDD:9443/ISomeService ), bekomme ich die Ausnahme java.security.cert.CertificateException: No subject alternative names present.

Um es zu beheben, lief ich zuerst openssl s_client -showcerts -connect AAA.BBB.CCC.DDD:9443 > certs.txt und habe folgenden Inhalt in der Datei certs.txt:

CONNECTED(00000003)
---
Certificate chain
 0 s:/CN=someSubdomain.someorganisation.com
   i:/CN=someSubdomain.someorganisation.com
-----BEGIN CERTIFICATE-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END CERTIFICATE-----
---
Server certificate
subject=/CN=someSubdomain.someorganisation.com
issuer=/CN=someSubdomain.someorganisation.com
---
No client certificate CA names sent
---
SSL handshake has read 489 bytes and written 236 bytes
---
New, TLSv1/SSLv3, Cipher is RC4-MD5
Server public key is 512 bit
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : RC4-MD5            
    Session-ID: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Session-ID-ctx:                 
    Master-Key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Key-Arg   : None
    Start Time: 1382521838
    Timeout   : 300 (sec)
    Verify return code: 21 (unable to verify the first certificate)
---

AFAIK, jetzt muss ich

  1. extrahieren Sie den Teil von certs.txt zwischen -----BEGIN CERTIFICATE----- und -----END CERTIFICATE-----,
  2. Ändern Sie es so, dass der Name des Zertifikats gleich ist AAA.BBB.CCC.DDD und
  3. importieren Sie dann das Ergebnis mit keytool -importcert -file fileWithModifiedCertificate (wo fileWithModifiedCertificate ist das Ergebnis der Operationen 1 und 2).

Ist das richtig?

Wenn ja, wie genau kann ich das Zertifikat aus Schritt 1 mit IP-basierter Adresse (AAA.BBB.CCC.DDD) ?

Update 1 (23.10.2013 15:37 MSK): Als Antwort auf eine ähnliche Frage habe ich folgendes gelesen:

Wenn Sie diesen Server nicht kontrollieren, verwenden Sie seinen Hostnamen (vorausgesetzt, es gibt mindestens einen CN, der mit diesem Hostnamen im vorhandenen Zertifikat übereinstimmt).

Was genau bedeutet “benutzen”?

  • Beantwortet das deine Frage? Beheben von javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX-Pfadaufbau fehlgeschlagen Fehler?

    – Rogerpack

    22. Februar 21 um 16:26 Uhr

Wie behebt man den Fehler „javasecuritycertCertificateException Keine alternativen Antragstellernamen vorhanden
Dmitrij Pisarenko

Ich habe das Problem behoben, indem ich HTTPS-Prüfungen mit dem vorgestellten Ansatz deaktiviert habe Hier:

Ich habe folgenden Code in die ISomeService Klasse:

static {
    disableSslVerification();
}

private static void disableSslVerification() {
    try
    {
        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }
            public void checkClientTrusted(X509Certificate[] certs, String authType) {
            }
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
            }
        }
        };

        // Install the all-trusting trust manager
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

        // Create all-trusting host name verifier
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };

        // Install the all-trusting host verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (KeyManagementException e) {
        e.printStackTrace();
    }
}

Da ich die benutze https://AAA.BBB.CCC.DDD:9443/ISomeService Nur für Testzwecke ist es eine gute Lösung, aber tun Sie dies nicht in der Produktion.

Beachten Sie, dass Sie SSL auch für “eine Verbindung nach der anderen” deaktivieren können, z. B.:

 // don't call disableSslVerification but use its internal code:
 HttpURLConnection conn = (HttpURLConnection) url.openConnection();
 if (conn instanceof HttpsURLConnection) {
    HttpsURLConnection httpsConn = (HttpsURLConnection) conn;
    httpsConn.setHostnameVerifier(allHostsValid);
    httpsConn.setSSLSocketFactory(sc.getSocketFactory());
 }

  • Der im oben genannten Link genannte Zugang scheint blockiert zu sein (nakov.com/blog/2009/07/16/…) . Kann jemand den Link aktualisieren?

    – John

    30. September 14 um 22:26 Uhr

  • Ich habe versucht, die Validierung bei diesem Vorgang zu deaktivieren, aber die Browservalidierung für SSL-Protokolle (Poodle-Schwachstelle) gibt mir Folgendes: ssl_error_no_cypher_overlap. Irgendwelche Ideen?

    – wird824

    28. Mai ’15 um 22:34 Uhr

  • Das Deaktivieren der HTTPS-Prüfung ist keine “Lösung”. Sie sollten sagen, dass ich einen “Patch” gefunden habe.

    – Jus12

    16. Mai 16 um 12:51 Uhr

  • Dies führt zu Sicherheitslücken in Pre_prod und Production. 1. Machen Sie einen Hosteintrag in der Windows-Hostdatei. 2. Oder fügen Sie IP- oder FQDN-Namen in den Feldern für alternative Antragstellernamen in den Zertifikaten hinzu

    – Shankar

    07.12.18 um 10:00 Uhr

  • Zertifikatsprüfung und Hostnamenprüfung gibt es aus gutem Grund. Während das Ignorieren aller Warnungen eine Problemumgehung sein kann, ist dies definitiv keine Lösung. Es widersetzt sich jeglicher Sicherheit, die SSL bieten soll.

    – Stefan Richter

    26. Januar 19 um 21:22 Uhr

Wie behebt man den Fehler „javasecuritycertCertificateException Keine alternativen Antragstellernamen vorhanden
juanmhidalgo

Ich habe das gleiche Problem und mit diesem Code gelöst. Diesen Code füge ich vor dem ersten Aufruf meiner Webservices ein.

javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
  new javax.net.ssl.HostnameVerifier(){

      public boolean verify(String hostname,
             javax.net.ssl.SSLSession sslSession) {
          return hostname.equals("localhost"); // or return true
      }
  });

Es ist einfach und funktioniert gut.

Hier ist die Originalquelle.

  • Oder Sie könnten einfach den gesamten Körper der Funktion verify() durch ersetzen return hostname.equals("localhost");, wenn Sie das möchten. Der if ist völlig überflüssig.

    – Nutzer

    30. Oktober 15 um 13:49 Uhr


  • Dies war eine einfache und schnelle Lösung, mit der wir das Testen in der Testumgebung eines Anbieters umgehen konnten, der kein ordnungsgemäßes Zertifikat hatte. Tausend Dank!

    – dacDave

    8. März 16 um 13:48 Uhr

  • @JuanM.Hidalgo, das hat bei mir funktioniert, platzierte den obigen Code direkt vor dem Aufruf an HttpsURLConnection connection = (HttpsURLConnection) obj.openConnection();. Ignoriert dies auch jedes Zertifikat? Da habe ich gesehen, dass ein solcher Workaround sicherheitsrelevant ist. Danke schön!

    – ThunderWiring

    2. April 16 um 9:01 Uhr

  • Diese Antwort löste meine SSL-Zertifikatsausnahme und das Problem mit Nicht-LDH-Zeichen. Ich konnte sehen, dass in Open JDK ein Fehler gemeldet wurde. bugs.openjdk.java.net/browse/JDK-8170265

    – Akhil S Kamath

    23. August 19 um 9:41 Uhr

  • Es funktioniert, obwohl es nur zu einem anderen Fehler weitergeht, das Deaktivieren von SSL funktionierte schließlich vollständig, stackoverflow.com/a/19542614/32453

    – Rogerpack

    22. Februar 21 um 15:51 Uhr

Dies ist eine alte Frage, aber ich hatte das gleiche Problem beim Wechsel von JDK 1.8.0_144 zu jdk 1.8.0_191

Wir haben einen Hinweis im Changelog gefunden:

Änderungsprotokoll

Wir haben die folgende zusätzliche Systemeigenschaft hinzugefügt, die in unserem Fall zur Lösung dieses Problems beigetragen hat:

-Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true

  • Es ist verrückt, aber niemand auf der Welt weiß, was diese Überprüfung tatsächlich verhindert. nur Ingenieure, die Dinge hinzufügen, weil sie es in einem Thoughtworks-Blog gelesen haben

    – bharal

    22. März 21 um 13:24 Uhr

  • @bharal Die Überprüfung verhindert Man-in-the-Middle-Angriffe auf Ihre sicheren Verbindungen. Deaktivieren Sie besser nicht die gesamte Zertifikatsüberprüfung, es sei denn, Sie sind sich zu 100 % sicher, dass sie nur in einer Entwicklungsumgebung verwendet wird.

    – mvreijn

    16. Dezember 21 um 13:48 Uhr


Die Überprüfung der Zertifikatsidentität wird anhand der Anforderungen des Clients durchgeführt.

Wenn Ihr Kunde verwendet https://xxx.xxx.xxx.xxx/something (wo xxx.xxx.xxx.xxx eine IP-Adresse ist), wird die Zertifikatsidentität gegen diese IP-Adresse geprüft (theoretisch nur mit einer IP-SAN-Erweiterung).

Wenn Ihr Zertifikat kein IP-SAN, sondern DNS-SANs hat (oder wenn kein DNS-SAN ein allgemeiner Name im Betreff-DN ist), können Sie dies zum Laufen bringen, indem Sie Ihren Client dazu bringen, stattdessen eine URL mit diesem Hostnamen (oder einem Hostnamen) zu verwenden für die das Zertifikat gültig wäre, wenn es mehrere mögliche Werte gibt). Wenn Ihr Zertifikat beispielsweise einen Namen für hat www.example.combenutzen https://www.example.com/something.

Natürlich benötigen Sie diesen Hostnamen, um zu dieser IP-Adresse aufzulösen.

Wenn DNS-SANs vorhanden sind, wird der CN im Betreff-DN außerdem ignoriert. Verwenden Sie in diesem Fall also einen Namen, der mit einem der DNS-SANs übereinstimmt.

1644322151 253 Wie behebt man den Fehler „javasecuritycertCertificateException Keine alternativen Antragstellernamen vorhanden
andreycpp

So importieren Sie das Zertifikat:

  1. Extrahieren Sie das Zertifikat vom Server, z openssl s_client -showcerts -connect AAA.BBB.CCC.DDD:9443 > certs.txt Dadurch werden Zertifikate im PEM-Format extrahiert.
  2. Konvertieren Sie das Zertifikat in das DER-Format, da Keytool dies erwartet, z openssl x509 -in certs.txt -out certs.der -outform DER
  3. Jetzt möchten Sie dieses Zertifikat in die Systemstandarddatei „cacert“ importieren. Suchen Sie die Systemstandarddatei „cacerts“ für Ihre Java-Installation. Werfen Sie einen Blick auf Wie erhalte ich den Speicherort von Cacerts der Standard-Java-Installation?
  4. Importieren Sie die Zertifikate in diese cacerts-Datei: sudo keytool -importcert -file certs.der -keystore <path-to-cacerts> Das Standardpasswort für Cacerts lautet „changeit“.

Wenn das Zertifikat für einen FQDN ausgestellt wird und Sie versuchen, eine Verbindung über die IP-Adresse in Ihrem Java-Code herzustellen, sollte dies wahrscheinlich in Ihrem Code behoben werden, anstatt mit dem Zertifikat selbst herumzuspielen. Ändern Sie Ihren Code, um eine Verbindung per FQDN herzustellen. Wenn der FQDN auf Ihrem Entwicklungscomputer nicht auflösbar ist, fügen Sie ihn einfach zu Ihrer Hosts-Datei hinzu oder konfigurieren Sie Ihren Computer mit einem DNS-Server, der diesen FQDN auflösen kann.

  • „Wenn der FQDN auf Ihrem Entwicklungscomputer nicht auflösbar ist, fügen Sie ihn einfach zu Ihrer Hosts-Datei hinzu“ – geholfen. Vielen Dank!

    – Woland

    16. November 17 um 16:28 Uhr

  • Ich habe das gleiche gemacht, aber das Problem besteht weiterhin. Gibt es noch etwas, das mit diesem Ansatz getan werden kann?

    – pkgajulapalli

    12. Januar 18 um 5:00 Uhr

1644322152 343 Wie behebt man den Fehler „javasecuritycertCertificateException Keine alternativen Antragstellernamen vorhanden
Eugen

Ich habe dieses Problem richtig behoben, indem ich die Betreff-Alt-Namen im Zertifikat hinzugefügt habe, anstatt Änderungen am Code vorzunehmen oder SSL zu deaktivieren, im Gegensatz zu den anderen Antworten, die hier vorgeschlagen werden. Wenn Sie deutlich sehen, dass die Ausnahme lautet: “Betreff-Alt-Namen fehlen”, also sollte der richtige Weg darin bestehen, sie hinzuzufügen

Bitte schau dir das an Link, um Schritt für Schritt zu verstehen.

Der obige Fehler bedeutet, dass Ihrer JKS-Datei die erforderliche Domäne fehlt, auf der Sie versuchen, auf die Anwendung zuzugreifen. Sie müssen Open SSL und das Schlüsseltool verwenden, um mehrere Domänen hinzuzufügen

  1. Kopieren Sie die openssl.cnf in ein aktuelles Verzeichnis
  2. echo '[ subject_alt_name ]' >> openssl.cnf
  3. echo 'subjectAltName = DNS:example.mydomain1.com, DNS:example.mydomain2.com, DNS:example.mydomain3.com, DNS: localhost'>> openssl.cnf
  4. openssl req -x509 -nodes -newkey rsa:2048 -config openssl.cnf -extensions subject_alt_name -keyout private.key -out self-signed.pem -subj '/C=gb/ST=edinburgh/L=edinburgh/O=mygroup/OU=servicing/CN=www.example.com/[email protected]' -days 365
  5. Exportieren Sie die Datei mit dem öffentlichen Schlüssel (.pem) in das PKS12-Format. Dies fordert Sie zur Eingabe des Passworts auf

    openssl pkcs12 -export -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES -export -in
    self-signed.pem -inkey private.key -name myalias -out keystore.p12
    
  6. Erstellen Sie a.JKS aus selbstsigniertem PEM (Keystore)

    keytool -importkeystore -destkeystore keystore.jks -deststoretype PKCS12 -srcstoretype PKCS12 -srckeystore keystore.p12
    
  7. Generieren Sie ein Zertifikat aus der obigen Keystore- oder JKS-Datei

    keytool -export -keystore keystore.jks -alias myalias -file selfsigned.crt
    
  8. Da das obige Zertifikat selbst signiert und nicht von der CA validiert ist, muss es im Truststore hinzugefügt werden (Cacerts-Datei unten im Speicherort für MAC, für Windows finden Sie heraus, wo Ihr JDK installiert ist.)

    sudo keytool -importcert -file selfsigned.crt -alias myalias -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/security/cacerts
    

Ursprüngliche Antwort gepostet auf diesen Link hier.

  • „Wenn der FQDN auf Ihrem Entwicklungscomputer nicht auflösbar ist, fügen Sie ihn einfach zu Ihrer Hosts-Datei hinzu“ – geholfen. Vielen Dank!

    – Woland

    16. November 17 um 16:28 Uhr

  • Ich habe das gleiche gemacht, aber das Problem besteht weiterhin. Gibt es noch etwas, das mit diesem Ansatz getan werden kann?

    – pkgajulapalli

    12. Januar 18 um 5:00 Uhr

Möglicherweise möchten Sie nicht die gesamte SSL-Verifizierung deaktivieren und können daher einfach die Überprüfung des Hostnamens deaktivieren, was etwas weniger beängstigend ist als die Alternative:

HttpsURLConnection.setDefaultHostnameVerifier(
    SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

[EDIT]

Wie von conapart3 erwähnt SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER ist jetzt veraltet, daher kann es in einer späteren Version entfernt werden, sodass Sie in Zukunft möglicherweise gezwungen sind, Ihre eigene zu erstellen, obwohl ich immer noch sagen würde, dass ich von allen Lösungen absehen würde, bei denen die gesamte Überprüfung deaktiviert ist.

  • SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER ist jetzt veraltet.

    – bonapart3

    27. März 17 um 17:35 Uhr

.

822460cookie-checkWie behebt man den Fehler „java.security.cert.CertificateException: Keine alternativen Antragstellernamen vorhanden“?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy