Java 调用 https 接口报错:javax.net.ssl.SSLException: Server key,这个报错原理有大神能科普一下吗?

yale268sh 发布于 01/27 10:43
阅读 196
收藏 0

JDK版本信息:
```java
java version "1.6.0_113"
Java(TM) SE Runtime Environment (build 1.6.0_113-b01)
Java HotSpot(TM) 64-Bit Server VM (build 20.111-b01, mixed mode)
```
Linux版本信息:
```java
Linux testUser 2.6.32-431.el6.x86_64 #1 SMP Sun Nov 10 22:19:54 EST 2013 x86_64 x86_64 x86_64 GNU/Linux
Linux version 2.6.32-431.el6.x86_64 (mockbuild@x86-023.build.eng.bos.redhat.com) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) ) #1 SMP Sun Nov 10 22:19:54 EST 2013
```


Weblogic版本
```java
WebLogic Server 10.3.6.0
weblogic11g,也就是10.3.6版本
```
JAVA代码中通过org.apache.http.client.methods.HttpPost(来自JAR包httpclient-4.5.9.jar)调用一个https的接口报错(第三方平台提供的接口,接口地址公司保密不能提供出来,类似https://testfile.comyan.org.cn/system/sc/qeuestUpload)。报错详细信息如下:

javax.net.ssl.SSLException: Server key
	at com.sun.net.ssl.internal.ssl.Handshaker.throwSSLException(Handshaker.java:1139)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:248)
	at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:817)
	at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:753)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:989)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1295)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1322)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1306)
	at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:436)
	at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:384)
	at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
	at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:374)
	at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
	at com.company.kb.common.utils.HttpUrlTool.sendHttpsAndSkipCertificate(HttpUrlTool.java:1528)
	at com.company.kb.policy.app.newest.platform.car.service.shenzhen.platservice.uploadPolicyInfo(VhlPlatformHandlerShenzhenNewestImpl.java:19083)
	at com.company.kb.policy.prod.vhl.bm.PolicyAppVhlBM.sendUrServiceBm(PolicyAppVhlBM.java:1002)
	at com.company.kb.policy.prod.vhl.bm.PolicyAppVhlBM.sendUrService(PolicyAppVhlBM.java:907)
	at com.company.kb.policy.app.quickapp.action.QuickAppBaseBizAction.sendUr(QuickAppBaseBizAction.java:2634)
	at sun.reflect.GeneratedMethodAccessor7523.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.apache.commons.beanutils.MethodUtils.invokeExactMethod(MethodUtils.java:404)
	at org.apache.commons.beanutils.MethodUtils.invokeExactMethod(MethodUtils.java:354)
	at com.isoftstone.fwk.facade.BizControllerImpl.handleRequest(BizControllerImpl.java:126)
	at com.isoftstone.fwk.facade.BizControllerPojoAdapter.handleRequest(BizControllerPojoAdapter.java:37)
	at com.isoftstone.fwk.action.BaseWebAction.perform(BaseWebAction.java:67)
	at sun.reflect.GeneratedMethodAccessor239.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.apache.commons.beanutils.MethodUtils.invokeExactMethod(MethodUtils.java:404)
	at org.apache.commons.beanutils.MethodUtils.invokeExactMethod(MethodUtils.java:354)
	at com.isoftstone.fwk.action.ActionControl.excute(ActionControl.java:19)
	at com.isoftstone.fwk.web.WebControl.doAction(WebControl.java:225)
	at com.isoftstone.fwk.web.WebControl.doPost(WebControl.java:47)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
	at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
	at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
	at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:301)
	at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
	at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:60)
	at com.isoftstone.fwk.web.filter.DWCallbackFilter.doFilter(DWCallbackFilter.java:110)
	at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:60)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:359)
	at org.springframework.security.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
	at org.springframework.security.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at org.springframework.security.ui.SessionFixationProtectionFilter.doFilterHttp(SessionFixationProtectionFilter.java:67)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at org.springframework.security.ui.ExceptionTranslationFilter.doFilterHttp(ExceptionTranslationFilter.java:101)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter.doFilterHttp(SecurityContextHolderAwareRequestFilter.java:91)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at org.springframework.security.ui.AbstractProcessingFilter.doFilterHttp(AbstractProcessingFilter.java:116)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at org.springframework.security.ui.logout.LogoutFilter.doFilterHttp(LogoutFilter.java:59)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpSessionContextIntegrationFilter.java:238)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:174)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:236)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
	at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:60)
	at org.jasig.cas.client.session.SingleSignOutFilter.doFilter(SingleSignOutFilter.java:99)
	at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:60)
	at com.isoftstone.iaeap.web.filter.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:97)
	at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:60)
	at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3748)
	at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3714)
	at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
	at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
	at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2283)
	at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2182)
	at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1499)
	at weblogic.work.ExecuteThread.execute(ExecuteThread.java:263)
	at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)
Caused by: java.security.spec.InvalidKeySpecException: key spec not recognised
	at cfca.sadk.org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi.engineGeneratePublic(BaseKeyFactorySpi.java:36)
	at cfca.sadk.org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi.engineGeneratePublic(KeyFactorySpi.java:89)
	at java.security.KeyFactory.generatePublic(KeyFactory.java:304)
	at com.sun.net.ssl.internal.ssl.HandshakeMessage$ECDH_ServerKeyExchange.<init>(HandshakeMessage.java:920)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:244)
	... 87 more
javax.net.ssl.SSLException: Server key
	at com.sun.net.ssl.internal.ssl.Handshaker.throwSSLException(Handshaker.java:1139)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:248)
	at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:817)
	at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:753)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:989)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1295)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1322)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1306)
	at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:436)
	at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:384)
	at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
	at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:374)
	at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
	at com.company.kb.common.utils.HttpUrlTool.sendHttpsAndSkipCertificate(HttpUrlTool.java:1528)
	at com.company.kb.policy.app.newest.platform.car.service.shenzhen.VhlPlatformHandlerShenzhenNewestImpl.uploadPolicyInfo(VhlPlatformHandlerShenzhenNewestImpl.java:19083)
	at com.company.kb.policy.prod.vhl.bm.PolicyAppVhlBM.undrDicision(PolicyAppVhlBM.java:1002)
	at com.company.kb.policy.prod.vhl.bm.PolicyAppVhlBM.quickSubmitToUnderwriting(PolicyAppVhlBM.java:907)
	at com.company.kb.policy.app.quickapp.action.QuickAppBaseBizAction.quickSubmitToUnderwriting(QuickAppBaseBizAction.java:2634)
	at sun.reflect.GeneratedMethodAccessor7523.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.apache.commons.beanutils.MethodUtils.invokeExactMethod(MethodUtils.java:404)
	at org.apache.commons.beanutils.MethodUtils.invokeExactMethod(MethodUtils.java:354)
	at com.isoftstone.fwk.facade.BizControllerImpl.handleRequest(BizControllerImpl.java:126)
	at com.isoftstone.fwk.facade.BizControllerPojoAdapter.handleRequest(BizControllerPojoAdapter.java:37)
	at com.isoftstone.fwk.action.BaseWebAction.perform(BaseWebAction.java:67)
	at sun.reflect.GeneratedMethodAccessor239.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.apache.commons.beanutils.MethodUtils.invokeExactMethod(MethodUtils.java:404)
	at org.apache.commons.beanutils.MethodUtils.invokeExactMethod(MethodUtils.java:354)
	at com.isoftstone.fwk.action.ActionControl.excute(ActionControl.java:19)
	at com.isoftstone.fwk.web.WebControl.doAction(WebControl.java:225)
	at com.isoftstone.fwk.web.WebControl.doPost(WebControl.java:47)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
	at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
	at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
	at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:301)
	at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
	at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:60)
	at com.isoftstone.fwk.web.filter.DWCallbackFilter.doFilter(DWCallbackFilter.java:110)
	at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:60)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:359)
	at org.springframework.security.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
	at org.springframework.security.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at org.springframework.security.ui.SessionFixationProtectionFilter.doFilterHttp(SessionFixationProtectionFilter.java:67)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at org.springframework.security.ui.ExceptionTranslationFilter.doFilterHttp(ExceptionTranslationFilter.java:101)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter.doFilterHttp(SecurityContextHolderAwareRequestFilter.java:91)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at org.springframework.security.ui.AbstractProcessingFilter.doFilterHttp(AbstractProcessingFilter.java:116)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at org.springframework.security.ui.logout.LogoutFilter.doFilterHttp(LogoutFilter.java:59)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpSessionContextIntegrationFilter.java:238)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371)
	at org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:174)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:236)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
	at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:60)
	at org.jasig.cas.client.session.SingleSignOutFilter.doFilter(SingleSignOutFilter.java:99)
	at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:60)
	at com.isoftstone.iaeap.web.filter.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:97)
	at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:60)
	at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3748)
	at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3714)
	at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
	at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
	at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2283)
	at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2182)
	at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1499)
	at weblogic.work.ExecuteThread.execute(ExecuteThread.java:263)
	at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)
Caused by: java.security.spec.InvalidKeySpecException: key spec not recognised
	at cfca.sadk.org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi.engineGeneratePublic(BaseKeyFactorySpi.java:36)
	at cfca.sadk.org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi.engineGeneratePublic(KeyFactorySpi.java:89)
	at java.security.KeyFactory.generatePublic(KeyFactory.java:304)
	at com.sun.net.ssl.internal.ssl.HandshakeMessage$ECDH_ServerKeyExchange.<init>(HandshakeMessage.java:920)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:244)
	... 87 more

项目中调用http接口的方法代码如下:

sendHttpsAndSkipCertificate这个是方法入口

private static CloseableHttpClient buildSSLCloseableHttpClient() throws Exception {
        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
            // 信任所有
            public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                return true;
            }
        }).build();
        // ALLOW_ALL_HOSTNAME_VERIFIER:这个主机名验证器基本上是关闭主机名验证的,实现的是一个空操作,并且不会抛出javax.net.ssl.SSLException异常。
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1" }, null,
                SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        return HttpClients.custom().setSSLSocketFactory(sslsf).build();
    }
public static String sendHttpsAndSkipCertificate(Map<String,String> httpMap, String jsonStr) throws BusinessServiceException {
    	long startTime = 0L;
    	long endTime = 0L;
        String result = null;// 返回的结果
        CloseableHttpResponse response = null;
        CloseableHttpClient client = null;
        HttpPost httpPost = new HttpPost(httpMap.get("url")); //创建HttpPost对象  
        // 参数不为空
        if(StringUtils.isNotBlank(jsonStr)) {
            try {  
    			//包装成一个Entity对象
    	        StringEntity entity = new StringEntity(jsonStr, CommCodeConstants.ENCODING_UTF_8);
    	        //设置请求的内容
    	        httpPost.setEntity(entity);
    	        //设置请求的报文头部的编码
    	        httpPost.setHeader(new BasicHeader("Content-Type", "application/json;charset=utf-8"));
    	        //设置期望服务端返回的编码
    	        httpPost.setHeader(new BasicHeader("Accept", "application/json, text/plain, */*"));
    	        //设置连接超时时间30秒
    	        httpPost.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 30000);
    	        //调用方法,创建 CloseableHttpClient 对象
                client = buildSSLCloseableHttpClient();
                startTime = System.currentTimeMillis();
                response = client.execute(httpPost);
                int statusCode = response.getStatusLine().getStatusCode();
                if(HttpURLConnection.HTTP_OK == statusCode) {
                    HttpEntity httpEntity = response.getEntity();  
                    //取出应答字符串 
                    result = EntityUtils.toString(httpEntity); 
                } else {
                	throw ExceptionUtil.createBusException("没有正确连接[" + httpMap.get("name") + "],HTTP服务返回有误,服务返回编码:" + statusCode);
                }
            } catch (Exception e) {
                endTime = System.currentTimeMillis() - startTime;
                logger.error("sendHttpsAndSkipCertificateError,endTime" + endTime, e);
                e.printStackTrace();  
                result = e.getMessage().toString();  
                throw ExceptionUtil.createBusException(httpMap.get("name") +"接口交互出错:"+e.getMessage().toString());
            }  finally {
    			if (response != null) {
    				try {//关闭response和client
    					response.close();
    				} catch(Exception e) {
    	                endTime = System.currentTimeMillis() - startTime;
    	                logger.error("sendHttpsAndSkipCertificateError,endTime" + endTime, e);
    					e.printStackTrace();
    				}
    			}
    			if (client != null) {
    				try {//关闭response和client
    					client.close();
    				} catch(Exception e) {
    	                endTime = System.currentTimeMillis() - startTime;
    	                logger.error("sendHttpsAndSkipCertificateError,endTime" + endTime, e);
    					e.printStackTrace();
    				}
    			}
    		}
        }
        return result;
    }


这个问题对我来说太难了。我个人猜测是我们公司服务器上面的证书有问题,但是我不知道怎么看服务器上面的证书。即使我看到了服务器上面的证书我也不知道怎么判断我们服务器上的证书有没有问题。我们生产环境上面调这个接口不会报错,测试环境上周测试的时候不会报错,昨天跟今天测试的时候每次调用都报错。

加载中
0
稀饭L1
稀饭L1

这种一般是找不到https的中间证书,一般有三种方法:

1.服务端调整https证书的配置加入中间证书

2.客户端信任所有证书(就是你目前这种)照理应该也是可以的,可能你哪里设置问题

3.手动生成证书加入到客户端JRE环境文件夹下(之前用过的方法)

下面具体第三种方法实现:

1.将下面类中域名替换为接口的域名

2.将生成的jssecacerts放到jre\lib\security目录下

package com.lk.hm.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

public class InstallCert {

    public static void main(String[] args) throws Exception {
        String host="域名";
        int port=443;
        char[] passphrase;
        String p ="changeit";
        passphrase = p.toCharArray();

        File file = new File("jssecacerts");
        if (file.isFile() == false) {
            char SEP = File.separatorChar;
            File dir = new File(System.getProperty("JAVA_HOME") + SEP + "lib"
                    + SEP + "security");
            file = new File(dir, "jssecacerts");
            if (file.isFile() == false) {
                file = new File(dir, "cacerts");
            }
        }
        System.out.println("Loading KeyStore " + file + "...");
        InputStream in = new FileInputStream(file);
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(in, passphrase);
        in.close();

        SSLContext context = SSLContext.getInstance("TLS");
        TrustManagerFactory tmf = TrustManagerFactory
                .getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(ks);
        X509TrustManager defaultTrustManager = (X509TrustManager) tmf
                .getTrustManagers()[ 0 ];
        SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
        context.init(null, new TrustManager[] { tm }, null);
        SSLSocketFactory factory = context.getSocketFactory();

        System.out
                .println("Opening connection to " + host + ":" + port + "...");
        SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
        socket.setSoTimeout(10000);
        try {
            System.out.println("Starting SSL handshake...");
            socket.startHandshake();
            socket.close();
            System.out.println();
            System.out.println("No errors, certificate is already trusted");
        } catch (SSLException e) {
            System.out.println();
            e.printStackTrace(System.out);
        }

        X509Certificate[] chain = tm.chain;
        if (chain == null) {
            System.out.println("Could not obtain server certificate chain");
            return;
        }

        BufferedReader reader = new BufferedReader(new InputStreamReader(
                System.in));

        System.out.println();
        System.out.println("Server sent " + chain.length + " certificate(s):");
        System.out.println();
        MessageDigest sha1 = MessageDigest.getInstance("SHA1");
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        for (int i = 0; i < chain.length; i++) {
            X509Certificate cert = chain[i];
            System.out.println(" " + (i + 1) + " Subject "
                    + cert.getSubjectDN());
            System.out.println("   Issuer  " + cert.getIssuerDN());
            sha1.update(cert.getEncoded());
            System.out.println("   sha1    " + toHexString(sha1.digest()));
            md5.update(cert.getEncoded());
            System.out.println("   md5     " + toHexString(md5.digest()));
            System.out.println();
        }

        System.out
                .println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
        String line = reader.readLine().trim();
        int k;
        try {
            k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
        } catch (NumberFormatException e) {
            System.out.println("KeyStore not changed");
            return;
        }

        X509Certificate cert = chain[k];
        String alias = host + "-" + (k + 1);
        ks.setCertificateEntry(alias, cert);

        OutputStream out = new FileOutputStream("jssecacerts");
        ks.store(out, passphrase);
        out.close();

        System.out.println();
        System.out.println(cert);
        System.out.println();
        System.out
                .println("Added certificate to keystore 'jssecacerts' using alias '"
                        + alias + "'");
    }

    private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();

    private static String toHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder(bytes.length * 3);
        for (int b : bytes) {
            b &= 0xff;
            sb.append(HEXDIGITS[b >> 4]);
            sb.append(HEXDIGITS[b & 15]);
            sb.append(' ');
        }
        return sb.toString();
    }

    private static class SavingTrustManager implements X509TrustManager {

        private final X509TrustManager tm;
        private X509Certificate[] chain;

        SavingTrustManager(X509TrustManager tm) {
            this.tm = tm;
        }

        public X509Certificate[] getAcceptedIssuers() {
            throw new UnsupportedOperationException();
        }

        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            throw new UnsupportedOperationException();
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            this.chain = chain;
            tm.checkServerTrusted(chain, authType);
        }
    }

}

 

yale268sh
yale268sh
谢谢,这个问题已经解决了。感谢你的回答。
0
yale268sh
yale268sh

已经解决了,详情见 https://club.perfma.com/question/2195295,解决办法就是升级了bcprov-jdkxxx-xxx.jar这个jar包。由bcprov-jdk16-1.46.jar升级到bcprov-jdk15on-160.jar就解决了。这个bcprov-jdkxxx-xxx.jar包在JDK的安装目录jre/lib/ext/这个目录下。同时还需要在JDK的安装目录/jre/lib/security/java.security这个文件中添加security.provider.9=org.bouncycastle.jce.provider.BouncyCastleProvider

0
yale268sh
yale268sh

但是还有一个疑问就是,我在本地测试的时候,就从来没报过这个错。我本地的环境是JDK1.6.0_45,tomcat6。而且我本地的JDK安装目录jre/lib/ext/这个目录下也没有bcprov-jdkxxx-xxx.jar这种格式的jar包。/jre/lib/security/java.security这个文件里面也没有security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider 这样的配置。我怀疑我们服务器上面有这个bcprov-jdkxxx-xxx.jar包,是我前任同事为了解决别的问题放上去的。然后有了这个bcprov-jdkxxx-xxx.jar包之后就会触发证书验证。其实没有这个bcprov-jdkxxx-xxx.jar包直接调https接口应该也不会报错。有了bcprov-jdkxxx-xxx.jar包刚好触发了https证书验证,但是服务器上这个bcprov-jdkxxx-xxx.jar包又不敢贸然删除,删了之后要大面积测试的。应该跟-DUseSunHttpHandler=true这个JVM参数也有关系。等我晚上下班测试一下。

OSCHINA
登录后可查看更多优质内容
返回顶部
顶部