本例采用openssl工具生成证书,应用服务器采用Jboss,利用cxf实现webservice。
首先安装java环境和openssl工具,opeenssl下载地址:
http://www.openssl.org/source/openssl-1.0.0.tar.gz.
然后进入openssl的bin目录下。
注:最好在安装linux环境下,在window环境下可能会出现问题。
在openssl的bin目录下创建文件夹:
mkdir root ---存放根证书目录
cd root
mkdir server ---存放服务端证书
mkdir client ---存放客户端证书
cd ..
创建根证书
创建私钥
openssl genrsa –out root/root-key.pem 1024
创建证书请求
openssl req -new -out root/root-req.csr -key root/root-key.pem -subj/C=CN/ST=GuangDong/L=GuangZhou/O="Huashetianzu Technologies Co.Ltd."/OU="Huashetianzu EOMS System Team"/OU="Copyright (c)1998-2008 Huashetianzu Technologies Co. Ltd."/CN="Huashetianzu EOMSRoot Authority"/[email protected]
自签署根证书
openssl x509 -req -in root/root-req.csr -out root/root-cert.pem -signkeyroot/root-key.pem -days 3650
导出证书
将根证书导出成浏览器可导入的PKCS12格式
openssl pkcs12 -export -clcerts -in root/root-cert.pem -inkeyroot/root-key.pem -out root/root-id.p12
注:此处要输入密码,记下这个密码,以后的配置中会用到这个密码。
创建服务端证书
创建私钥
openssl genrsa -out root/server/temip-key.pem 1024
创建证书请求
openssl req -new -out root/server/temip-req.csr -keyroot/server/temip-key.pem -subj /C=CN/ST=GuangDong/L=GuangZhou/O="HuashetianzuTechnologies Co. Ltd."/OU="Huashetianzu EOMS SystemTeam"/OU="Copyright (c) 1998-2008 Huashetianzu Technologies Co.Ltd."/CN=82.208.35.148/[email protected]
注:cn如果是本机应该填写localhost,如果是网站则填写域名。
签署服务器端证书
openssl x509 -req -in root/server/temip-req.csr -outroot/server/temip-cert.pem -CA root/root-cert.pem -CAkey root/root-key.pem-CAcreateserial -days 3650
导出证书
将服务器端证书导出成浏览器可导入的PKCS12格式
openssl pkcs12 -export -clcerts -inroot/server/temip-cert.pem -inkey root/server/temip-key.pem -outroot/server/temip-id.p12
注:此处要输入密码,记下这个密码,以后的配置中会用到这个密码。
将证书导入到JKS文件中
keytool -import -v -trustcacerts -storepass changeit -alias temip -fileroot/server/temip-cert.pem -keystore root/server/temip-id.jks
注:输入“y”,然后回车。
创建客户端证书
首先创建根证书签发的客户端证书颁发机构的二级证书,再以此二级证书来签发客户端证书
二级证书制作
创建私钥
openssl genrsa -out root/client/eomsca-key.pem 1024
创建证书请求
openssl req -new -out root/client/eomsca-req.csr -keyroot/client/eomsca-key.pem -subj /C=CN/ST=GuangDong/L=GuangZhou/O="HuashetianzuTechnologies Co. Ltd."/OU="Huashetianzu EOMS SystemTeam"/OU="Copyright (c) 1998-2008 Huashetianzu Technologies Co.Ltd."/CN="Huashetianzu EOMS Secure ServerAuthority"/[email protected] -reqexts v3_req
自签署客户端证书
openssl x509 -req -in root/client/eomsca-req.csr -outroot/client/eomsca-cert.pem -signkey root/client/eomsca-key.pem -CAroot/root-cert.pem -CAkey root/root-key.pem -CAcreateserial -days 3650
导出证书
将客户端证书导出成浏览器可导入的PKCS12格式
openssl pkcs12 -export -clcerts -in root/client/eomsca-cert.pem-inkey root/client/eomsca-key.pem -out root/client/eomsca-id.p12
注:此处要输入密码,记下这个密码,以后的配置中会用到这个密码。
将证书导入到JKS文件中
keytool -import -v -trustcacerts -storepass changeit -alias eomsca -fileroot/client/eomsca-cert.pem -keystore root/client/eomsca-id.jks
注:输入“y”,然后回车。
客户端证书
创建客户端证书,并自用根证书签署
创建私钥
openssl genrsa -out root/client/hw_Huashetianzu-key.pem 1024
创建证书请求
openssl req -new -out root/client/hw_Huashetianzu-req.csr -keyroot/client/hw_Huashetianzu-key.pem -subj/C=CN/ST=GuangDong/L=GuangZhou/O="Huashetianzu Technologies Co.Ltd."/OU="Huashetianzu EOMS System Team"/OU="Copyright (c)1998-2008 Huashetianzu Technologies Co.Ltd."/CN=localhost/[email protected]
二级证书签署客户端证书
openssl x509 -req -in root/client/hw_Huashetianzu-req.csr-out root/client/hw_Huashetianzu-cert.pem -signkey root/client/hw_Huashetianzu-key.pem-CA root/client/eomsca-cert.pem -CAkey root/client/eomsca-key.pem-CAcreateserial -days 3650
导出证书
将客户端证书导出成浏览器可导入的PKCS12格式
openssl pkcs12 -export -clcerts -in root/client/hw_Huashetianzu-cert.pem-inkey root/client/hw_Huashetianzu-key.pem -out root/client/hw_Huashetianzu-id.p12
注:此处要输入密码,记下这个密码,以后的配置中会用到这个密码。
将证书导入到JKS文件中
keytool -import -v -trustcacerts -storepass changeit-alias client -file root/client/hw_Huashetianzu-cert.pem -keystoreroot/client/hw_Huashetianzu-id.jks
注:输入“y”,然后回车。
CXFhttps双向配置
服务端配置
首先把刚才生成的server文件夹下的temip-id.p12文件和client文件夹下的eomsca-id.p12文件拷贝到Jboss的安装目server/default/conf下。然后修改Jboss安装目录下的server\default\deploy\jboss-web.deployer下的server.xml文件,打开server.xml文件,去掉大约在30-40行的注释,修改成如下的内容:
<Connector port="8443" address="0.0.0.0"protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150"scheme="https" secure="true clientAuth="true"sslProtocol="TLS" keystoreFile="conf/temip-id.p12"
keystoreType="PKCS12"keystorePass="服务器端证书的密码"truststoreFile="conf/eomsca-id.p12" truststoreType="PKCS12"truststorePass="客户端证书的密码"/>
注:clientAuth="true" 表示https采用的双向认证,即服务端需要验证客户端,客户端也需要验证服务端。clientAuth=”false”;表示单向认证。如果采用双向认证,还需要把服务器端的证书导入到你所使用的jre路径中,完整命令如下:keytool -import -file temip-cert.pem -keystore %java_home%/jre/lib/security/cacerts 此时,会让你输入keystore的密码,默认密码是“changeit”。
把client文件夹下的hw_Huashetianzu-id.p12证书导入浏览器,在浏览器中输入:https://服务器端ip:8443进行访问。
客户端配置
采用代码式
// 创建WebService服务工厂
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
// 注册WebService接口 factory.setServiceClass(CIPB2BServiceAssuranceWorkForceClientManagementPortType.class);
String wsdlAdder = getRemeySA_URL();
// 发布接口
factory.setAddress(wsdlAdder);
SAAJInInterceptor saajInInterceptor = new SAAJInInterceptor();
List interceptors = new ArrayList();
interceptors.add(saajInInterceptor);
factory.setInInterceptors(interceptors);
SAAJOutInterceptor saajOutInterceptor = new SAAJOutInterceptor();
List outerceptorList = new ArrayList();
outerceptorList.add(saajOutInterceptor);
factory.setOutInterceptors(outerceptorList);
CIPB2BServiceAssuranceWorkForceClientManagementPortType cipb2bServiceProvisioningWorkForceClientManagementPortType = (CIPB2BServiceAssuranceWorkForceClientManagementPortType) factory.create();
Client proxy = ClientProxy.getClient(cipb2bServiceProvisioningWorkForceClientManagementPortType);
HTTPConduit conduit = (HTTPConduit) proxy.getConduit();
TLSClientParameters tlsParams = conduit.getTlsClientParameters();
if (tlsParams == null)
{
tlsParams = new TLSClientParameters();
}
tlsParams.setTrustManagers(getTrustManagers());
tlsParams.setKeyManagers(getKeyManagers());
tlsParams.setDisableCNCheck(true);
tlsParams.setSecureSocketProtocol("SSL");
conduit.setTlsClientParameters(tlsParams);
private static KeyManager[] getKeyManagers()
{
InputStream is = null;
try
{
// 获取默认的 X509算法
String alg = KeyManagerFactory.getDefaultAlgorithm();
// 创建密钥管理工厂
KeyManagerFactory factory = KeyManagerFactory.getInstance(alg);
File certFile = new File(KEYMANAGER_PATH);
if (!certFile.exists() || !certFile.isFile())
{
return null;
}
is = new FileInputStream(certFile);
// 构建以证书相应格式的证书仓库
KeyStore ks = KeyStore.getInstance(KEYSTORE_TYPE);
// 加载证书
ks.load(is, KEYMANAGER_PASSWORD.toCharArray());
factory.init(ks, KEYMANAGER_PASSWORD.toCharArray());
KeyManager[] keyms = factory.getKeyManagers();
return keyms;
}
catch (Exception e)
{
logger.error("getKeyManagers faiure", e);
}
finally
{
if (is != null)
{
try
{
is.close();
}
catch (IOException e)
{
logger.error("close failure", e);
}
}
}
return null;
}
private static TrustManager[] getTrustManagers()
{
// 读取证书仓库输入流
InputStream is = null;
try
{
// 信任仓库的默认算法X509
String alg = TrustManagerFactory.getDefaultAlgorithm();
// 获取信任仓库工厂
TrustManagerFactory factory = TrustManagerFactory.getInstance(alg);
// 读取信任仓库
is = new FileInputStream(new File(TRUSTMANAGER_PATH));
// 密钥类型
KeyStore ks = KeyStore.getInstance(TRUSTORE_TYPE);
// 加载密钥
ks.load(is, TRUSTMANGER_PASSWORD.toCharArray());
factory.init(ks);
TrustManager[] tms = factory.getTrustManagers();
return tms;
}
catch (Exception e)
{
logger.error("getTrustManagers failure", e);
}
finally
{
if (is != null)
{
try
{
is.close();
}
catch (IOException e)
{
logger.error("close Io failure", e);
}
}
}
return null;
}
采用spring方式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:soap="http://cxf.apache.org/bindings/soap"
xmlns:sec="http://cxf.apache.org/configuration/security"
xmlns:http="http://cxf.apache.org/transports/http/configuration"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd
http://cxf.apache.org/bindings/soap
http://cxf.apache.org/schemas/configuration/soap.xsd
http://cxf.apache.org/configuration/security
http://cxf.apache.org/schemas/configuration/security.xsd
http://cxf.apache.org/transports/http/configuration
http://cxf.apache.org/schemas/configuration/http-conf.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<context:component-scan base-package="com.test" />
<!-- webserice接收客户端,address为服务器webservice接口地址 -->
<jaxws:client id="userService"
address="https://10.78.194.92:8443/webserviceserver/service/user" serviceClass="com.test.UserService"/>
<http:conduit name="*.http-conduit">
<http:tlsClientParameters disableCNCheck="true">
<!-- keyPassword客户端证书密码,file为客户端证书位置 -->
<sec:keyManagers keyPassword="123456789">
<sec:keyStore type="PKCS12" password="123456789"
file="C:\\Users\\ckf55689\\Desktop\\root\\client\\hw_Huashetianzu-id.p12" />
</sec:keyManagers>
<sec:cipherSuitesFilter>
<sec:include>.*_EXPORT_.*</sec:include>
<sec:include>.*_EXPORT1024_.*</sec:include>
<sec:include>.*_WITH_DES_.*</sec:include>
<sec:include>.*_WITH_NULL_.*</sec:include>
<sec:exclude>.*_DH_anon_.*</sec:exclude>
</sec:cipherSuitesFilter>
</http:tlsClientParameters>
</http:conduit>
</beans>