How to Fix the "Java.Security.Cert.Certificateexception: No Subject Alternative Names Present" Error

How to fix the java.security.cert.CertificateException: No subject alternative names present error?

I fixed the problem by disabling HTTPS checks using the approach presented here:

I put following code into the the ISomeService class:

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();
}
}

Since I'm using the https://AAA.BBB.CCC.DDD:9443/ISomeService for testing purposes only, it's a good enough solution, but do not do this in production.

Note that you can also disable SSL for "one connection at a time" ex:

 // 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());
}

Java CertificateException No subject alternative names matching IP address ... found

Your certificate should include that ip value as a subject alternative name value (of type IPAddress : key=7).

http://web.archive.org/web/20160201235032/http://www.jroller.com/hasant/entry/no_subject_alternative_names_matching

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names matching IP address

Well, if the API is hosted on an IP address, the SSL certificate has to define that IP address as Subject Alternative Name. This however won't work for services like Let's Encrypt.

I guess the main cause of the issue is that you're trying to access the API by its IP address rather than its FQDN. Changing the URL of the API to the appropriate DNS name for the IP address in your source code should yield in everything working, as long as the DNS name resolves to something related to the domain the wildcard certificate was issued for (e.g. api.myappdomain.au).

CertificateException: No subject alternative names present

The CN (Common name) i.e. IP on certificate is different and the IP i am calling is different.

...

HTTP transport error: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present.

When a name is present in the Common Name (CN), it must also be present in the Subject Alternate Name (SAN). You have a malformed certificate (and it might have other problems). See Baseline Requirements for the Issuance and Management of Publicly-Trusted Certificates, Section 9 (pages 9 & 10):

9.2.2 Subject Common Name Field

Certificate Field: subject:commonName (OID 2.5.4.3)

Required/Optional: Deprecated (Discouraged, but not prohibited)

Contents: If present, this field MUST contain a single IP address or
Fully-Qualified Domain Name that is one of the values contained in the
Certificate’s subjectAltName extension (see Section 9.2.1).

Bruno can probably cite the relevant section from RFC 6125.

SSLHandshakeException: No subject alternative names present

Thanks,Bruno for giving me heads up on Common Name and Subject Alternative Name. As we figured out certificate was generated with CN with DNS name of network and asked for regeneration of new certificate with Subject Alternative Name entry i.e. san=ip:10.0.0.1. which is the actual solution.

But, we managed to find out a workaround with which we can able to run on development phase. Just add a static block in the class from which we are making ssl connection.

static {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()
{
public boolean verify(String hostname, SSLSession session)
{
// ip address of the service URL(like.23.28.244.244)
if (hostname.equals("23.28.244.244"))
return true;
return false;
}
});
}

If you happen to be using Java 8, there is a much slicker way of achieving the same result:

static {
HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> hostname.equals("127.0.0.1"));
}

Mule - java.security.cert.CertificateException: No subject alternative names present

You're sending an HTTPS request to 0.0.0.0 and the certificate you're running there doesn't list 0.0.0.0 as SAN.

You should either:

  • Change the request host to match what is in your certificate,
  • Add a SAN for 0.0.0.0 in the certificate.

No subject alternative names present exception when creating web service client

You seem to be confused between "importing" and "generating" the certificate.

You openssl s_client command doesn't generate the certificate, it retrieves the certificate in use on that server.

The keytool -import command you use afterwards imports that certificate, as it is, into your truststore. There is no point using -ext san=ip:xxx.xx.xx.xx there: you're not generating the certificate, you're only importing it.

If you're in control of that server, you should generate (or get a certificate from somewhere else) with an IP address SAN (since Java follows the specification strictly on this).

If you're not in control of that server, use its host name (provided that there is at least a CN matching that host name in the existing cert).

In general, it's not great to import directly a certificate obtained solely from a server like this into your trust store, since you're assuming that that particular connection wasn't tampered with.



Related Topics



Leave a reply



Submit