首页 > 解决方案 > javax.net.ssl.SSLHandshakeException:java.security.cert.CertificateException:没有与 IP 地址匹配的主题备用名称

问题描述

我有一个调用外部 api 的 java 应用程序,它托管在https://10.20.30.40:1234/test/myurl 之类的地址上

这有一个带有 CN 的域基础证书,例如 *.myappdomain.au

我们已经在我们的 linux 服务器上完成了证书的注册。我什至尝试使用以下代码加载证书,但它没有用,我们得到同样的错误

private static SSLSocketFactory createSSLSocketFactory(String certificatePath) throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        File crtFile = new File(certificatePath);
        
        Certificate certificate = CertificateFactory.getInstance("X.509").generateCertificate(new FileInputStream(crtFile));

        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, null);
        keyStore.setCertificateEntry("server", certificate);

        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(keyStore);

        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustManagerFactory.getTrustManagers(), null);

        return sslContext.getSocketFactory();
    }

我尝试过的一件事是在 10.20.30.40 myappdomain.au 之类的主机中添加条目,然后使用 https://myappdomain.au:1234/test/myurl之类的 url

然后应用程序工作

知道我还需要做什么

标签: javassl-certificate

解决方案


好吧,如果 API 托管在 IP 地址上,则 SSL 证书必须将该 IP 地址定义为Subject Alternative Name。但是,这不适用于Let's Encrypt 之类的服务。

我想问题的主要原因是您试图通过其 IP 地址而不是其 FQDN 访问 API。将 API 的 URL 更改为源代码中 IP 地址的适当 DNS 名称应该会在所有工作中产生效果,只要 DNS 名称解析为与颁发通配符证书的域相关的内容(例如api.myappdomain.au)。


推荐阅读