webservice启用tomcat ssl双向认证之后,使用事先写好的webservice客户端访问
服务端的接口https://localhost:8443/WSDemo/SurveyWebService,具体客户端类如下public class SurveyServiceClient
{
public static void main(String[] args)
{
System.setProperty("javax.net.ssl.keyStore", "G:/SSL/keystore/client.p12");
System.setProperty("javax.net.ssl.keyStorePassword", "client");
System.setProperty("javax.net.ssl.keyStoreType", "PKCS12");
System.setProperty("javax.net.ssl.trustStore", "G:/SSL/keystore/tomcat.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "testpass");
// 加载客户端的配置定义
ApplicationContext context = new
ClassPathXmlApplicationContext("beanRefClient.xml");
// 获取定义的 Web Service Bean
ISurveyService surveyService =
(ISurveyService)context.getBean("surveyServiceClient");
// 1、定义调查投票的变量与内容,用来发送给服务
String username = "Test";
int point = 88;
// 调用方法进行服务消费
String result = surveyService.vote(username,point);
System.out.println("Result:" + result);
// 2、传递不一样的调查投票内容
username = "Michael";
point = 100;
// 再次调用方法进行服务消费,得到不一样的结果
result = surveyService.vote(username,point);
System.out.println("Result:" + result);
// 3、第三次传递与调用
username = "Jordan";
point = 9;
result = surveyService.vote(username,point);
System.out.println("Result:" + result);
}
}客户端main方法如上,但是访问的时候出现异常如下:org.apache.cxf.interceptor.Fault: Could not send Message.
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:64)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:532)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:464)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:367)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:320)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:89)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)
at $Proxy31.vote(Unknown Source)
at ws.cxf.client.SurveyServiceClient.main(SurveyServiceClient.java:26)
Caused by: javax.net.ssl.SSLHandshakeException: SSLHandshakeException invoking https://localhost:8443/WSDemo/SurveyWebService: java.security.cert.CertificateException: No X509TrustManager implementation available
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.mapException(HTTPConduit.java:1458)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1443)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:659)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
... 9 more
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No X509TrustManager implementation available
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)客户端里边是不是还需要加上什么代码,请高手指点啊,谢谢!另外还有一个疑问,ssl协议是不是只能起到握手,确认双方证书身份,然后双方得到对称密钥的作用?那么具体的证书验证应该怎么实现呢,怎么确保客户端和服务端通信的数据被保护呢?
客户端和服务端
服务端的接口https://localhost:8443/WSDemo/SurveyWebService,具体客户端类如下public class SurveyServiceClient
{
public static void main(String[] args)
{
System.setProperty("javax.net.ssl.keyStore", "G:/SSL/keystore/client.p12");
System.setProperty("javax.net.ssl.keyStorePassword", "client");
System.setProperty("javax.net.ssl.keyStoreType", "PKCS12");
System.setProperty("javax.net.ssl.trustStore", "G:/SSL/keystore/tomcat.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "testpass");
// 加载客户端的配置定义
ApplicationContext context = new
ClassPathXmlApplicationContext("beanRefClient.xml");
// 获取定义的 Web Service Bean
ISurveyService surveyService =
(ISurveyService)context.getBean("surveyServiceClient");
// 1、定义调查投票的变量与内容,用来发送给服务
String username = "Test";
int point = 88;
// 调用方法进行服务消费
String result = surveyService.vote(username,point);
System.out.println("Result:" + result);
// 2、传递不一样的调查投票内容
username = "Michael";
point = 100;
// 再次调用方法进行服务消费,得到不一样的结果
result = surveyService.vote(username,point);
System.out.println("Result:" + result);
// 3、第三次传递与调用
username = "Jordan";
point = 9;
result = surveyService.vote(username,point);
System.out.println("Result:" + result);
}
}客户端main方法如上,但是访问的时候出现异常如下:org.apache.cxf.interceptor.Fault: Could not send Message.
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:64)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:532)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:464)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:367)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:320)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:89)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)
at $Proxy31.vote(Unknown Source)
at ws.cxf.client.SurveyServiceClient.main(SurveyServiceClient.java:26)
Caused by: javax.net.ssl.SSLHandshakeException: SSLHandshakeException invoking https://localhost:8443/WSDemo/SurveyWebService: java.security.cert.CertificateException: No X509TrustManager implementation available
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.mapException(HTTPConduit.java:1458)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1443)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:659)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
... 9 more
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No X509TrustManager implementation available
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)客户端里边是不是还需要加上什么代码,请高手指点啊,谢谢!另外还有一个疑问,ssl协议是不是只能起到握手,确认双方证书身份,然后双方得到对称密钥的作用?那么具体的证书验证应该怎么实现呢,怎么确保客户端和服务端通信的数据被保护呢?
客户端和服务端
提示的错误,表示你根本就没有实现证书访问的代码。需要自己覆写个SSLSocketFactory,来做SSL连接。
—— SSL协议主责是握手并建立后续安全通讯信道,可以理解为得到对称密钥;
—— 但握手过程包含对证书的验证,不受信证书是无法双向握手的;◎ 那么具体的证书验证应该怎么实现呢,怎么确保客户端和服务端通信的数据被保护呢?
—— 首先某证书本身是需要根证书进行签发的,其签发过程可以理解为是根证书用私钥对该证书进行了签名;
—— 那么验证过程实际上就是用根证书的公钥对该证书进行验签,如果验签通过说明该证书是有效的(即该证书确实是由受信根证书所颁发)
—— 另外还有一个问题是吊销列表,也就是对于被吊销的证书,需要有个专用列表。
—— 那么你应该会注意到Tomcat和浏览器实际上都有对于受信根证书链的配置,就是用来做证书验证的。
另外看网上说有个truststore文件,这个truststore和keystore文件有什么不同?
嗯,那就是说证书的验证是ssl协议自动给你验证的是吧?
—— 是的。将客户端cer文件导入服务端的keystore文件,这些就是证书的验证工作吧?
—— 不是,这是准备工作,但我认为你理解错误;keystore是存储服务器端证书的。这个truststore和keystore文件有什么不同?
—— 如前所述,keystore存储服务器端证书(包含私钥,安全性要求很高);truststore保存信任证书(只需要公钥部分);
可参见:
http://lukejin.iteye.com/blog/605634
webservice 框架cxf生成的客户端代码怎么验证服务端的证书,求高人指点啊,这个问题我上网查了,也试了,感觉都不行,郁闷啊
A wsdl_first_https sample can be found in the CXF distribution with more detail. Also see this blog entry for another example.2个sample我觉得应该能搞清楚了吧。官方的文档唉
调用客户端代码之前,先调用如下函数:
public final static void init(){
System.setProperty("javax.net.ssl.trustStore", "G:\\SSL\\jks\\truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "123456");
System.setProperty("javax.net.ssl.trustStoreType", "JKS");
System.setProperty("javax.net.ssl.keyStore", "G:\\SSL\\client\\client.p12");
System.setProperty("javax.net.ssl.keyStorePassword", "123456");
System.setProperty("javax.net.ssl.keyStoreType","PKCS12");
}
就是死活出不来,悲剧啊,想不通是为啥
JDK 1.6 或以上版本:keytool -importcerts -alias server -file server.cer -keystore truststore.jksserver.cer 是服务器端 X.509 证书
truststore.jks 是你的信任库
alias 取了一个别名如果加上 -trustcacerts 参数,会将该证书导到 JRE 的 CA 信任库中
ca证书,客户端证书,和服务端证书,然后用cxf配置的方法弄出来了,但是具体代码实现不行,试了无数次了都不行,很不甘心,我qq362315157,不麻烦的话加下我,我给你发具体点的信息过去,帮我看看,如果解决了,我会把解决方法发上来大家共享一下!
System.setProperty("javax.net.ssl.keyStore", "d:/lcl.p12");
System.setProperty("javax.net.ssl.keyStorePassword", "aaaaaaa");
System.setProperty("javax.net.ssl.keyStoreType", "PKCS12");
System.setProperty("javax.net.ssl.trustStore", "d:/tomcat.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "aaaaaaa"); Service serviceModel = new ObjectServiceFactory().create(IHelloWebService.class);
IHelloWebService service=null;
try {
service = (IHelloWebService) new XFireProxyFactory().create(serviceModel, serviceURL);
} catch (MalformedURLException e) {
logger.error("初始化xx网webService失败," + e);
}
System.setProperty("javax.net.debug", "all");
System.err.println(service.sayHello("杨mmm"));