出现SSLHandshakeException:无本主题替代名称出现SSLHandshakeExce

2019-05-13 14:19发布

我通过Java代码调用HTTPS SOAP的Web服务。 我已经进口的JRE的cacerts密钥库自签名证书。 现在,我得到:

com.sun.xml.internal.ws.com.client.ClientTransportException: HTTP transport error: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present

服务URL的主机名不匹配的CN CERT中提供。 我读到有关定义自定义主机名验证的解决办法在这里 。 但我不能能够做出我应该实现我的代码的解决方法。

public SOAPMessage invokeWS(WSBean bean) throws Exception {

    SOAPMessage response=null;
    try{

    /** Create a service and add at least one port to it. **/
    String targetNameSpace = bean.getTargetNameSpace();
    String endpointUrl = bean.getEndpointUrl();
    QName serviceName = new QName(targetNameSpace, bean.getServiceName());
    QName portName = new QName(targetNameSpace, bean.getPortName());
    String SOAPAction = bean.getSOAPAction();
    HashMap<String, String> map = bean.getParameters();


    Service service = Service.create(serviceName);
    service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, endpointUrl);

    /** Create a Dispatch instance from a service. **/
    Dispatch dispatch = service.createDispatch(portName, SOAPMessage.class,
            Service.Mode.MESSAGE);

    // The soapActionUri is set here. otherwise we get a error on .net based
    // services.
    dispatch.getRequestContext().put(Dispatch.SOAPACTION_USE_PROPERTY,
            new Boolean(true));
    dispatch.getRequestContext().put(Dispatch.SOAPACTION_URI_PROPERTY,
            SOAPAction);

    /** Create SOAPMessage request. **/
    // compose a request message
    MessageFactory messageFactory = MessageFactory.newInstance();
    SOAPMessage message = messageFactory.createMessage();

    // Create objects for the message parts
    SOAPPart soapPart = message.getSOAPPart();
    SOAPEnvelope envelope = soapPart.getEnvelope();
    SOAPBody body = envelope.getBody();

    SOAPElement bodyElement = body.addChildElement(bean.getInputMethod(),
            bean.getPrefix(), bean.getTargetNameSpace());

             ...more code to form soap body goes here

    // Print request
    message.writeTo(System.out);

    // Save the message
    message.saveChanges();

    response = (SOAPMessage)dispatch.invoke(message);
    }
    catch (Exception e) {
        log.error("Error in invokeSiebelWS :"+e);
    }
    return response;
}

作为命名空间和其他WSDL属性从这个bean来请忽略WSBean参数。 如果此异常可以用一些不同的解决方法来解决,请不要建议。

Answer 1:

谢谢,布鲁诺给我上的通用名称和主题备用名称抬起头来。 正如我们想通了与CN生成的证书与网络的DNS名称,并要求与主题备用名称项即SAN = IP新证书的再生:10.0.0.1。 这是实际解决方案

但是,我们设法找到了,使我们可以能够在开发阶段运行的解决方法 。 就在从中我们正在SSL连接类添加静态块。

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

如果你碰巧使用Java 8,是实现相同的结果的一个更巧妙方式:

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


Answer 2:

不像某些浏览器的Java遵循HTTPS规范严格,当涉及到服务器身份验证(RFC 2818第3.1节)和IP地址。

当使用主机名,有可能回落到通用名称的服务器证书的主题DN,而是采用了主题备用名称。

如果使用IP地址,必须有证书的主题备用名称项(类IP地址,而不是DNS名称)。

你会发现有关规范以及如何生成此类证书的详细细节这个答案 。



文章来源: SSLHandshakeException: No subject alternative names present