关于AXIS WebService通过HTTPS协议访问WAS Web服务错误问题的解决方案
问题:
近期我的合作伙伴在WebSphere Application Sever服务器平台上使用Apache AXIS WebServcie客户端调用 WAS/WPS平台上提供的WebService 服务器时,WebService 客户端出现了以下的错误信息:
faultCode:{http://schemas.xmlsoap.org/soap/envelope/}Server.userException |
针对这种访问问题到底如何解决呢?
为此必须知道 IBM JDK JSSE SSL 访问的基本原理。
SSL 协议基于公钥密码,加密密钥成对地出现在公钥密码中,它们是在数学上是相关的,但无法由一个推知另一个。这对加密密钥由私有密钥和公有密钥(私有,公共)组成的。私有密钥一直处于其所属实体的保护之下。注意,所有者确实拥有这对加密密钥,但公共密钥,如同它的名称所示,可以为众所周知,或至少自由地分散到与公共/私有密钥对通信的实体中。公钥密码启用的安全性服务是基于这样的消息解密机制,即共有密钥只能通过相应的私有密钥才能解密,反之亦然。这样,如果使用实体的公钥加密消息,那么可以保证只有该实体能够解密此消息。这时会在脑海中立即出现一个问题,即怎样确保正在使用的公钥的确被绑定到合法实体上而没有绑定到其它实体上。在此 Public Key Infrastructures(PKI)开始起作用了。
客户端和服务器信任库/密钥库间的关系
当将 JSSE 用于 SSL 通信时,需要在本地存储中维护一套信任的签名者的证书,由此得名信任库。例如,由 JSSE 运行时使用的客户端信任库为了验证试图连接到服务器的客户端确实使用合法的证书(由信任的签名者发出的)与服务器交互。因此,服务器证书的签名者必须持有保存在客户端信任库中的 PKC。
上图“客户端和服务器信任库/密钥库间的关系”的上面一个图示就是描述了这种场景:当使用AXIS引擎通过HTTPS协议访问后台WAS Web服务时,底层使用的是JSSE SSL通讯协议。在这种场景下,JSSE SSL客户端必须保存服务器后台的公钥到客户端的信任证书中,而大家使用是WAS缺省自签的证书,而JRE Cacerts中是不会信任此自签证书的,从而出现上面错误日志中的“com.ibm.jsse2.util.h: No trusted certificate found ”异常。
那我们如何解决此问题呢?
解决方案有两种:
A、在WAS/WPS服务器使用第三方签署的证书,由于此证书是官方签署的,而此官方根证书(信任公钥)缺省存在于JRE/lib/security/cacerts文件中,从而解决了WebService SSL访问WAS/WPS 后台WebService安全证书问题。
B、如果条件不允许使用第三方官方签发的证书(毕竟要花费大量的银子),那我们必须采用以下方法来应对此问题。其实通过上面我们SSL原理性的介绍,相信大家应该初步知道如何去解决此问题。为了大家的方便,我就一步一步把详细过程记录如下(以下以WASv6.1为例,其他版本WAS操作方式基本相近):
1、首先找到后台提供WebService服务WAS服务器的Server KeyStore文件,一般此文件缺省存在于您创建WAS Profiles目录的etc目录下,比如profiles/wps/etc/key.p12
2、在WAS/WPS profiles实例的bin目录下,执行ikeyman工具,从key.p12 密钥库中抽取出 WAS Web服务 HTTPS所使用的公钥。
输入WAS自签证书库密码:WebAS
点击“个人证书”中的“default”证书,然后使用“抽取证书…”按钮,来导出WAS证书公钥
3、同样在WAS/WPS profiles实例的bin目录下,执行ikeyman工具,把key.p12 密钥库中抽取出 WAS Web服务 HTTPS所使用的公钥导入到JRE cacerts信任公钥库中。
打开jre/lib/security/cacerts信任公钥库文件。
输入密钥库保护密码changeit
此时我们可以看到目前在JSSE所有的信任公钥
此时点击“添加…”按钮把WAS/WPS服务器中导出的公钥添加到此信任公钥库中
针对此导入的公钥,取一个易于识别的证书标号
此时我们可以看到,服务器公钥已经被成功导入到客户端(服务器)的JSSE 信任密钥库中了
小结
至此通过以上的手段,相信可以解决原先出现的Apache AXIS WebServcie客户端调用 WAS/WPS平台上提供的WebService 服务器出现了证书异常的错误,从而最终解决问题。