0

I want to verify the hostname of a given certificate (X509Certificate object). That is, to check whether the hostname matches any of the hostnames listed in the certificate's "Subject Alternative Name" or "Common Name" field.

I read online that you can import javax.net.ssl.HostnameVerifier and then use HttpsURLConnection.getDefaultHostnameVerifier().verify(...) to do that. However, the verify function takes an SSLSession object so it won't work with an X509Certificate object.

I would appreciate your help. Thanks.

Ido
  • 397
  • 2
  • 7
  • 22

1 Answers1

1

In order to verify that the hostname provided by the server is included in the hostnames included in the certificate's CN or SAN you need to read the hostname from the connection and the SAN & CN from the cert as follows:

   String host = connection.getURL().getHost();

   Collection<List<?>> subjectAlternativeNames = x509.getSubjectAlternativeNames();

   String name = x509.getSubjectX500Principal().getName();
   String cn = name.replace("(?:^|,\\s?)(?:CN=(?<val>\"(?:[^\"]|\"\")+\"|[^,]+)", "$1");

Note that when an SSL connection is established that's exactly what the HostnameVerifier does.

John Williams
  • 4,252
  • 2
  • 9
  • 18
  • Is it possible to call a third-party utility function to do that for me? From a security aspect, it is usually better to rely on libraries and not implement the logic manually. – Ido Mar 24 '23 at 05:39
  • 1
    This check is done automatically by the internal hostnameverifier when establishing an SSL connection. Doing it like this is redundant. If you insist then bouncy castle (https://github.com/bcgit/bc-java) has everything you need. Maybe start at line 243 here https://github.com/neoeinstein/bouncycastle/blob/master/crypto/src/crypto/tls/TlsProtocolHandler.cs – John Williams Mar 24 '23 at 08:00