如何修复“java.security.cert.CertificateException:不存在主题替代名称"错误? [英] How to fix the "java.security.cert.CertificateException: No subject alternative names present" error?

查看:28
本文介绍了如何修复“java.security.cert.CertificateException:不存在主题替代名称"错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Java Web 服务客户端,它通过 HTTPS 使用 Web 服务.

I have a Java web service client, which consumes a web service via HTTPS.

import javax.xml.ws.Service;

@WebServiceClient(name = "ISomeService", targetNamespace = "http://tempuri.org/", wsdlLocation = "...")
public class ISomeService
    extends Service
{

    public ISomeService() {
        super(__getWsdlLocation(), ISOMESERVICE_QNAME);
    }

当我连接到服务 URL (https://AAA.BBB.CCC.DDD:9443/ISomeService) 时,我收到异常 java.security.cert.CertificateException:不存在主题替代名称.

When I connect to the service URL (https://AAA.BBB.CCC.DDD:9443/ISomeService ), I get the exception java.security.cert.CertificateException: No subject alternative names present.

为了修复它,我首先运行 openssl s_client -showcerts -connect AAA.BBB.CCC.DDD:9443 >certs.txt 并在文件 certs.txt 中得到以下内容:

To fix it, I first ran openssl s_client -showcerts -connect AAA.BBB.CCC.DDD:9443 > certs.txt and got following content in file certs.txt:

CONNECTED(00000003)
---
Certificate chain
 0 s:/CN=someSubdomain.someorganisation.com
   i:/CN=someSubdomain.someorganisation.com
-----BEGIN CERTIFICATE-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END CERTIFICATE-----
---
Server certificate
subject=/CN=someSubdomain.someorganisation.com
issuer=/CN=someSubdomain.someorganisation.com
---
No client certificate CA names sent
---
SSL handshake has read 489 bytes and written 236 bytes
---
New, TLSv1/SSLv3, Cipher is RC4-MD5
Server public key is 512 bit
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : RC4-MD5            
    Session-ID: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Session-ID-ctx:                 
    Master-Key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Key-Arg   : None
    Start Time: 1382521838
    Timeout   : 300 (sec)
    Verify return code: 21 (unable to verify the first certificate)
---

AFAIK,现在我需要

AFAIK, now I need to

  1. 提取-----BEGIN CERTIFICATE----------END CERTIFICATE--之间的certs.txt部分---,
  2. 修改它使证书名称等于AAA.BBB.CCC.DDD
  3. 然后使用 keytool -importcert -file fileWithModifiedCertificate 导入结果(其中 fileWithModifiedCertificate 是操作 1 和 2 的结果).
  1. extract the part of certs.txt between -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----,
  2. modify it so that the certificate name is equal to AAA.BBB.CCC.DDD and
  3. then import the result using keytool -importcert -file fileWithModifiedCertificate (where fileWithModifiedCertificate is the result of operations 1 and 2).

这是正确的吗?

如果是这样,我如何才能使第 1 步中的证书与基于 IP 的地址(AAA.BBB.CCC.DDD)一起使用?

If so, how exactly can I make the certificate from step 1 work with IP-based adddress (AAA.BBB.CCC.DDD) ?

更新 1 (23.10.2013 15:37 MSK): 在回答 类似问题,我读到以下内容:

Update 1 (23.10.2013 15:37 MSK): In an answer to a similar question, I read the following:

如果您无法控制该服务器,请使用其主机名(提供在现有的主机名中至少有一个 CN 匹配该主机名证书).

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).

使用"究竟是什么意思?

What exactly does "use" mean?

推荐答案

我通过使用提供的方法禁用 HTTPS 检查解决了这个问题 这里:

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

我将以下代码放入 ISomeService 类:

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

由于我使用 https://AAA.BBB.CCC.DDD:9443/ISomeService 仅用于测试目的,因此这是一个足够好的解决方案,但不要在生产中使用.

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.

请注意,您还可以为一次一个连接"禁用 SSL;例如:

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.security.cert.CertificateException:不存在主题替代名称"错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆