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所示。
图 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所示。
图 12-40 Windows安全
点击“确定”按钮,并在弹出的“申请使用密钥的权限”对话框中选择“授予权限”选项,并单击“确定”按钮,完成设置,如图12-41所示。
图 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所示。
图 12-42 SOAP交互内容
此处,我们使用了服务器证书私钥对上述内容解密,这说明在双向认证的网络交互中,服务器证书用于加密/解密,而客户证书仅用于验证客户身份。