Ivan
Ivan

Reputation: 55

java.security.cert.CertificateException when connecting to server with multiple certificates

I'm trying to create SSL connection to a website (https://www.otten-markenshop.de/), and using browser or curl it works, but neither wget, no Java manages to connect. I am mostly interested in why does Java code fail. Here are the error details:

Using WGET:

wget https://www.otten-markenshop.de/

results in

Resolving www.otten-markenshop.de... 217.24.213.167
Connecting to www.otten-markenshop.de|217.24.213.167|:443... connected.
ERROR: certificate common name “www.plentymarkets.eu” doesn’t match requested 
host name “www.otten-markenshop.de”.

Using Java:

public static void main(String[] args) throws IOException
{
    URL url = new URL("https://www.otten-markenshop.de");
    URLConnection connection = url.openConnection();
    connection.getInputStream();
}

results in:

Exception in thread "main" javax.net.ssl.SSLHandshakeException: 
java.security.cert.CertificateException: No subject alternative DNS 
name matching www.otten-markenshop.de found.

What else I have noticed is that certificate I receive in browser is different from the certificate I receive when running Java program:

in browser:

Common Name (CN): 
    www.otten-markenshop.de
Subject Alternative Name: 
    DNS Name=www.otten-markenshop.de 
    DNS Name=otten-markenshop.de

in Java:

Common Name (CN): 
    www.plentymarkets.eu
Subject Alternative Name: 

And the certificate I get in Java is the same as I would receive in browser if I try to access the host by IP address: https://217.24.213.167 Thus it appears that server has multiple certificates installed and uses virtual hosts to detect which certificate should be used. But for some reason this detection does not work when client is Java or wget.

Any ideas why is this happening?

P.S. I don't have access to the destination server to see how it is configured.

P.P.S. I am interested more in understanding why the simple Java code does not work, rather than making it work by, for instance, disabling the SSL verification. After all I can connect to the mentioned URL over HTTP without any issues.

Upvotes: 0

Views: 1203

Answers (1)

Bruno
Bruno

Reputation: 122729

Having multiple certificates on the same IP address and port relies on Server Name Indication.

Your server supports it, but your client needs to support it too.

Client-side support for SNI was only introduced in Java in Java 7 (see release notes)(*). I guess you're using Java 6 or below, otherwise your simple example with URLConnection should work out of the box like this.

(You may also need additional settings if you're using another client library, such as Apache HTTP Client, depending on the version.)

(*) And this was introduced on the server side in Java 8, but that's not really your problem here.

Upvotes: 1

Related Questions