12.3.3 安全升级2—双向认证服务

如果我们开放了Web Service系统,并向合作方颁发了该系统的服务器证书,虽然可以确保SOAP交互安全,但却无法确认合作方的身份。假如有其他竞争对手冒充合作方,则可以很轻易地获得我方的商业数据,这将直接导致数据泄露,这种情况对于公司是相当可怕的。这时,我们有必要对合作方进行身份验证。针对这一需求,我们可以通过双向认证服务满足。

1.构建证书

在单向认证服务的基础上,我们构建客户证书用于验证客户身份。完成命令如代码清单12-47所示。

代码清单12-47 构建客户证书


echo产生客户私钥private/client.key.pem

openssl genrsa-des3-out private/client.key.pem 2048

echo生成客户证书请求private/client.csr

openssl req-new-key private/client.key.pem-out

private/client.csr-subj"/C=CN/ST=BJ/L=BJ/O=zlex/OU=zlex/CN=zlex"

echo签发客户证书private/client.cer

openssl ca-in private/client.csr-days 3650-out

certs/client.cer-cert certs/ca.cer-keyfile private/ca.key.pem-notext

echo客户证书转换private/client.p12

openssl pkcs12-export-inkey private/client.key.pem-in certs/client.cer-out

certs/client.p12


❑导入证书

为方便演示,需将客户证书个人信息交换文件client.p12导入IE浏览器。请读者参照ca.p12文件导入方式导入client.p12文件,注意输入客户证书密码(这里为“123456”),并确认导入该证书。

最终,我们将在“个人”选项卡中找到我们导入的客户证书,如图12-39所示。

figure_0452_0180

图 12-39 导入客户证书

2.配置Tomcat

我们在单向认证配置的基础上稍加修改,即可完成双向认证服务配置。server.xml文件详细配置如代码清单12-48所示。

代码清单12-48 server.xml配置—双向认证


<Connector

clientAuth="true"

SSLEnabled="true"

maxThreads="150"

port="443"

protocol="HTTP/1.1"

scheme="https"

secure="true"

sslProtocol="TLS"

keystoreFile="conf/server.p12"

keystorePass="123456"

keystoreType="PKCS12"

truststoreFile="conf/ca.p12"

truststorePass="123456"

truststoreType="PKCS12"/>


这里我们需要将客户端验证开关打开,即将参数clientAuth值设置为“true”。

重新启动Tomcat,通过IP直接访问地址https://192.168.184.131/axis/services,我们将先得到“Windows安全”对话框,如图12-40所示。

figure_0453_0181

图 12-40 Windows安全

点击“确定”按钮,并在弹出的“申请使用密钥的权限”对话框中选择“授予权限”选项,并单击“确定”按钮,完成设置,如图12-41所示。

figure_0453_0182

图 12-41 申请使用密钥权限

最终,我们将得到服务列表,与图12-27一致。

3.验证服务

构建双向认证服务,客户端需要导入客户证书,这里我们需要修改init()方法,同时初始化信任库配置和密钥库配置。

信任库相关属性请参见12.3.2节内容,密钥库相关属性详细描述如下:

❑javax.net.ssl.keyStore:指向密钥库文件路径。

❑javax.net.ssl.keyStoreType:密钥库文件类型。

❑javax.net.ssl.keyStorePassword:密钥库密码。

此时,我们需要将服务器个人信息交换文件client.p12放置在D盘根目录下。初始化证书配置方法实现如代码清单12-49所示。

代码清单12-49 初始化证书配置—双向认证


//初始化证书配置

@Before

public final void init(){

//配置信任库

System.setProperty("javax.net.ssl.trustStore","D:\server.p12");

System.setProperty("javax.net.ssl.trustStorePassword","123456");

System.setProperty("javax.net.ssl.trustStoreType","PKCS12");

//配置密钥库

System.setProperty("javax.net.ssl.keyStore","D:\client.p12");

System.setProperty("javax.net.ssl.keyStoreType","PKCS12");

System.setProperty("javax.net.ssl.keyStorePassword","123456");

}


此处我们仅需要配置密钥库,即将“javax.net.ssl.keyStore”属性指向文件client.p12,并指定密钥库文件类型,即将“javax.net.ssl.keyStoreType”属性值置为“PKCS12”。同时,指定密钥库密码,即将“javax.net.ssl.keyStorePassword”属性值设置为“123456”。

双向认证服务完整代码如代码清单12-50所示。

代码清单12-50 SOAP响应测试用例—双向认证


import static org.junit.Assert.*;

import java.net.URL;

import javax.xml.namespace.QName;

import org.apache.axis.client.Call;

import org.apache.axis.client.Service;

import org.junit.Before;

import org.junit.Test;

/**

*WebService测试

*@author梁栋

*@version 1.0

*@since 1.0

*/

public class WebServiceTest{

//Namespace URL

private String namespaceUri="https://192.168.184.131/axis/services/Version";

//WSDL URL

private String wsdlUrl="https://192.168.184.131/axis/services/Version?wsdl";

//初始化证书配置

@Before

public final void init(){

//配置信任库

System.setProperty("javax.net.ssl.trustStore","D:\server.p12");

System.setProperty("javax.net.ssl.trustStorePassword","123456");

System.setProperty("javax.net.ssl.trustStoreType","PKCS12");

//配置密钥库

System.setProperty("javax.net.ssl.keyStore","D:\client.p12");

System.setProperty("javax.net.ssl.keyStoreType","PKCS12");

System.setProperty("javax.net.ssl.keyStorePassword","123456");

}

/**

*测试

*@throws Exception

*/

@Test

public final void test()throws Exception{

//创建调用对象

Service service=new Service();

Call call=(Call)service.createCall();

//调用远程方法

call.setOperationName(new QName(namespaceUri,"getVersion"));

//设置URL

call.setTargetEndpointAddress(new URL(wsdlUrl));

//执行远程调用,同时获得返回值

String version=(String)call.invoke(new Object[]{});

//打印信息

System.err.println(version);

//验证

assertNotNull(version);

}

}


此时,我们可以通过加密方式进行SOAP请求和回复操作。同时,我们一样可以通过Wireshark监测并解析加密SOAP数据。

4.网络监测

参照12.3.2节内容,对Wirdshark进行SSL/TLS协议配置,并在Wireshark过滤器地址栏中输入过滤信息筛选SSL/TLS协议数据包,如代码清单12-51所示。

代码清单12-51 过滤拦截4


(ip.src==192.168.184.131&&ip.dst==192.168.184.1)||(ip.dst==192.168.184.131&&ip.src==192.168.184.1)&&ssl


其中


(ip. src==192.168.184.131&&ip.dst==192.168.184.1)指限定由本机请求虚拟机

(ip. dst==192.168.184.131&&ip.src==192.168.184.1)指限定由虚拟机回复本机

ssl 指定SSL/TLS协议


重新执行SOAP响应测试用例(双向认证),在Wireshark中监测到的SSL/TLS交互内容。右键单击任意一条数据包,在弹出的菜单中选择“Follow TCP Stream”菜单项。我们同样可以获得解密的SOAP交互内容,如图12-42所示。

figure_0456_0183

图 12-42 SOAP交互内容

此处,我们使用了服务器证书私钥对上述内容解密,这说明在双向认证的网络交互中,服务器证书用于加密/解密,而客户证书仅用于验证客户身份。