CertificateException: No name matching ssl.someUrl.de found
Asked Answered
G

9

66

I'm trying to connect to one of my servers through ssl, with Java. I tried a lot of options here is my best try:

I generate a jssecacerts with the recommendet script: http://blogs.oracle.com/andreas/resource/InstallCert.java with the command: java InstallCert ssl.someUrl.de changeit

after this I did the command a second time:

Loading KeyStore jssecacerts...
Opening connection to ssl.someUrl.de:443...
Starting SSL handshake...

No errors, certificate is already trusted

Server sent 1 certificate(s):

 1 Subject [email protected], CN=plesk, OU=Plesk, O=Parallels, L=Hernd
on, ST=Virginia, C=US
   Issuer  [email protected], CN=plesk, OU=Plesk, O=Parallels, L=Hernd
on, ST=Virginia, C=US
   sha1    f1 0d 2c 54 05 e1 32 19 a0 52 5e e1 81 6c a3 a5 83 0d dd 67
   md5     f0 b3 be 5e 5f 6e 90 d1 bc 57 7a b2 81 ce 7d 3d

Enter certificate to add to trusted keystore or 'q' to quit: [1]

I copied the file to the default directory and I loaded the certificate in Java trustStore

System.setProperty("javax.net.ssl.trustStore", "C:\\Program Files (x86)\\Java\\jre6\\lib\\security\\jssecacerts");
System.setProperty("javax.net.ssl.trustStorePassword","changeit");

Then I try to connect

URL url = new URL("https://ssl.someUrl.de/");
URLConnection conn = url.openConnection();
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));

And I get Error on 3rd line: (No name matching ssl.someUrl.de found)

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching ssl.someUrl.de found

Is this cause of the default plesk certificate or is something else wrong?

Setup: JRE 6.20, Netbeans 6.8, Windows7 64bit

Glimp answered 22/6, 2010 at 12:35 Comment(0)
C
83

It looks like the certificate of the server you are trying to connect to doesn't match its hostname.

When an HTTPS client connects to a server, it verifies that the hostname in the certificate matches the hostname of the server. It's not enough for a certificate to be trusted, it has to match the server you want to talk to too. (As an analogy, even if you trust a passport to be legitimate, you still have to check that it's the one for the person you want to talk to, not just any passport you would trust to be legitimate.)

In HTTP, this is done by checking that:

  • the certificate contains a DNS subject alternative name (this is a standard extension) entry matching the hostname;

  • failing that, the last CN of your subject distinguished name (this is the main name if you want) matches the hostname. (See RFC 2818.)

It's hard to tell what the subject alternative name is without having the certificate (although, if you connect with your browser and check its content in more details, you should be able to see it.) The subject distinguished name seems to be:

[email protected], CN=plesk, OU=Plesk, O=Parallels, L=Herndon, ST=Virginia, C=US

(It would thus need to be CN=ssl.someUrl.de instead of CN=plesk, if you don't have a subject alternative name with DNS:ssl.someUrl.de already; my guess is that you don't.)

You may be able to bypass the hostname verification using HttpsURLConnection.setHostnameVerifier(..). It shouldn't be too hard to write a custom HostnameVerifier that bybasses the verification, although I would suggest doing it only when the certificate its the one concerned here specifically. You should be able to get that using the SSLSession argument and its getPeerCertificates() method.

(In addition, you don't need to set the javax.net.ssl.* properties the way you've done it, since you're using the default values anyway.)

Alternatively, if you have control over the server you're connecting to and its certificate, you can create a certificate of it that matches the naming rules above (CN should be sufficient, although subject alternative name is an improvement). If a self-signed certificate is good enough for what you name, make sure its common name (CN) is the host name you're trying to talk to (no the full URL, just the hostname).

Conquer answered 22/6, 2010 at 13:42 Comment(6)
thx I did it with the HostnameVerifier. I just need a crypted connection. There is only one client and one server, with a fixed htts:// adress.Glimp
Remember that you need some form of identity verification of encryption to provide security. Otherwise, it's like exchanging secrets with someone you don't know: however good the secrecy method is, that doesn't really protect you.Conquer
but i know the server and the the only client (which is on my computer) and no one can read the stream of data. And the https page is also protected with a simple htaccess. Or am I getting it wrong ?Glimp
Well, it depends on how you're sure no one can read the stream of data. If you do feel you need SSL to protect the communication, then you do need to check that the remote certificate is the one you want to communicate with. Making a manual exception like you're doing is fine, but you still need to check that it's indeed the exception you want to make.Conquer
@Conquer I am trying to install the ssl in kafka using localhost. Will localhost work ?and what will be the case if I have the IP address of the system on which I am installing certificates.Tumbler
@Tumbler I can confirm this solution worksTurmeric
R
54

In Java 8 you can skip server name checking with the following code:

HttpsURLConnection.setDefaultHostnameVerifier ((hostname, session) -> true);

However this should be used only in development!

Rigobertorigor answered 2/9, 2014 at 16:7 Comment(2)
great, thanks. more help here: mkyong.com/webservices/jax-ws/…Hieroglyphic
@Hieroglyphic interestingly answer didn't work but the link you shared worked. I'm puzzled. Is this required to be implemented static way ?Lablab
S
20

I created a method fixUntrustCertificate(), so when I am dealing with a domain that is not in trusted CAs you can invoke the method before the request. This code will gonna work after java1.4. This method applies for all hosts:

public void fixUntrustCertificate() throws KeyManagementException, NoSuchAlgorithmException{


        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) {
                }

            }
        };

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };

        // set the  allTrusting verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
}
Sinegold answered 21/11, 2015 at 18:25 Comment(2)
I setup reverse proxy to call another https service and this solution fix all my problem. With other solution, besides the java.security.cert.CertificateException: No name matching imobileqaf.mobile.medcity.net found, the other exception come out later, such as sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target and java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty.Thissa
I am glad to know, I use this approach a long time ago. For production environment always is better to have a valid signed certificate, although self signed certificates are much better than nothing!Sinegold
M
7

If you're looking for a Kafka error, this might because the upgrade of Kafka's version from 1.x to 2.x.

javax.net.ssl.SSLHandshakeException: General SSLEngine problem ... javax.net.ssl.SSLHandshakeException: General SSLEngine problem ... java.security.cert.CertificateException: No name matching *** found

or

[Producer clientId=producer-1] Connection to node -2 failed authentication due to: SSL handshake failed

The default value for ssl.endpoint.identification.algorithm was changed to https, which performs hostname verification (man-in-the-middle attacks are possible otherwise). Set ssl.endpoint.identification.algorithm to an empty string to restore the previous behaviour. Apache Kafka Notable changes in 2.0.0

Solution: SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, ""

Metope answered 8/4, 2019 at 7:42 Comment(2)
So i've been struggling with this all day today, I had already added the ssl.endpoint.identification.algorithm to server.properties but everytime i wanted to use a consumer or producer i.e ./kafka-console-producer.sh --broker-list fs:9094 --topic test --producer.config ../config/producer.properties with of course the ssl properties on the consumer.properties for the client jks etc i was still getting an error, so i decided to throw the above ssl.endpoint.identification.algorithm on consumer.properties and it seems to have fixed it.Runesmith
Thank you for posting this.. I can here because of the kafka issue...Lowrie
I
5

I've found a good resolution here: http://www.mkyong.com/webservices/jax-ws/java-security-cert-certificateexception-no-name-matching-localhost-found/

But my problem was a little bit different and solved it differently.

The web service was on remote host. For example: https://some.remote.host/MyWebService?wsdl

But it was available only by IP for any clients, but certificate was created for domain: some.remote.host (CN=some.remote.host). And this domain can't be resolved by IP because it is not presented in DNS).

So the same problem appeared: if I use IP to connect to web service by ssl, it can't be reached becase certificate CN=some.remote.host and it is not equal to host name I've specified (i.e. host IP).

I've resolved it by matching this hostname with IP in /etc/hosts file. The problem was fixed.

But in case when the Web Service is hosted on localhost app server, it think, it should be solved like mkyong described in his article.

Inerrable answered 10/7, 2013 at 4:51 Comment(0)
H
5

Use case: i am using a self-signed certificate for my development on localhost.

Error: Caused by: java.security.cert.CertificateException: No name matching localhost found

Solution: When you generate your self-signed certificate, make sure you answer this question like that:

What is your first and last name?
  [Unknown]:  localhost

//The rest you can fill accordingly


As a bonus, here are my steps:

1. Generate self-signed certificate:

keytool -genkeypair -alias netty -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 4000
Enter keystore password: ***
Re-enter new password: ***

What is your first and last name?
  [Unknown]:  localhost

//The rest you can fill accordingly

2. Copy the certificate in src/main/resources(if necessary)

3. Update the cacerts

keytool -v -importkeystore -srckeystore keystore.p12 -srcstoretype pkcs12 -destkeystore "%JAVA_HOME%\jre\lib\security\cacerts" -deststoretype jks

4. Update your config(in my case application.properties):

server.port=8443
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=jumping_monkey
server.ssl.key-store-type=pkcs12
server.ssl.key-alias=netty
Harlem answered 31/1, 2020 at 8:0 Comment(0)
C
1

The server name should be same as the first/last name which you give while create a certificate

Clevis answered 25/7, 2013 at 13:52 Comment(0)
A
0

one can skip the hostname verification by setting a VM property:

-Djdk.internal.httpclient.disableHostnameVerification

This works with Java 11 HttpClient implementation.

Apiculate answered 19/4, 2021 at 12:51 Comment(1)
Gave a chance to Java 8 but fails. :)Waterer
C
0
HttpsURLConnection.setDefaultHostnameVerifier((String hostname, SSLSession sslSession) -> {
        return hostname.equals("localhost");
    });

add this to your method from where you calling the server.

Conveyancer answered 3/9, 2021 at 6:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.