公司项目需要,之前研究了WebService CXF 的安全机制(Security),找的资料都是自定义拦截器(如WebService(6)_CXF拦截器-权限管理-登录验证这篇文章)。
但其实这种方法是伪安全的,仔细看看拦截器的日志,可以发现拦截器日志中报文的参数都是明文发送的,等于没有加密...
后来发现CXF 支持数字证书加密,找了很多例子,不过发布的CXF都是集成在Spring中的,最后找到这个,不需要集成Spring,也可以集成数字证书。
http://nogrief.iteye.com/blog/795814
只是博主写的比较潦草,Demo写了好几次才跑通..现在将这个整理一下,给大家一个参考。
这里我把Demo上传了,有兴趣的可以下载下来跑跑试试看
Demo_WebService_CXF_x509
有网友问我,运行上面这个Demo,抛出签名和解密无效的错误,该怎么解决...
是这样的,上面这个Demo如果要运行的话,需要更新一下秘钥,因为秘钥的使用是有 有效期的,具体秘钥怎么生成继续往下看就知道了...
-------更新于2017-10-03
CXF安全机制
X509
X509是一种非常通用的证书格式。所有的证书都符合ITU-TX.509国际标准,因此(理论上)为一种应用创建的证书可以用于任何其他符合X.509标准的应用。
提到X509,需要理解下面相关概念
- Private ket
- Public key
- keyStore
- TrustStore
Private key和 Public key就是字面意思,公钥和私钥
KeyStore和 TrustStore就是存储私钥和密钥的容器,二者从结构上都是一样的,只不过概念上有区分。
KeyStore主要用来存储私钥
TrustStore主要用来存储公钥
更多相关x509的信息,去百度吧,暂时没研究.
CXF与 X509
在CXF中,使用加密签名的方式作为安全策略,配置上有些麻烦
流程图如下
简单解释下
- 客户端发送消息到服务端
- 客户端A使用A自己的私钥进行签名,使用服务端B的公钥进行加密,然后消息发送到服务端B,B用自己的私钥进行解密,用A的公钥进行验签
- 服务端返回消息到客户端
- 服务端B用自己的私钥进行签名,使用A的公钥进行加密,然后将消息发送给客户端A,A用私钥进行解密,用B的公钥进行验签。
仔细想想这个过程,理解之后,感觉不是太复杂。
实现代码
生成证书
生成证书的话,咱们使用JDK自带的一个工具 -- keytool
- 首先创建客户端公钥和KeyStore
keytool -genkey -alias clientprivatekey -keypass keypass -keystore Client_KeyStore.jks -storepass storepass -dname "CN=tongtech.com,C=CN" -keyalg RSA
创建KeyStore,文件名为Client_KeyStore.jks,里面有一个名为clientprivatekey的私钥。
- 给私钥进行签名
keytool -selfcert -keystore Client_KeyStore.jks -storepass storepass -alias clientprivatekey -keypass keypass
签名成功的话,无任何提示
- 导出私钥
作用是将导出的证书作为公钥保存到TrustStore中。
keytool -export -alias clientprivatekey -file Client_PublicCert.cer -keystore Client_KeyStore.jks -storepass storepass
如果成功,可以看到提示:"存储在文件<Client_PublicCert.cer>中的证书"
然后创建服务端KeyStore
- 创建私钥和KeyStore
keytool -genkey -aliasserverprivatekey-keypass keypass -keystore Server_KeyStore.jks -storepass storepass -dname "CN=tongtech.com,C=CN" -keyalg RSA
- 用私钥进行签名
keytool -selfcert -keystore Server_KeyStore.jks -storepass storepass -aliasserverprivatekey -keypass keypass
- 导出私钥
keytool -export -aliasserverprivatekey -file Server_PublicCert.cer -keystore Server_KeyStore.jks -storepass storepass
- 接下来,将客户端公钥导入到服务端的TrustStore中,将服务端公钥导入到客户端TrustStore中
keytool -import -aliasclientpublickey -file Client_PublicCert.cer -keystore Server_TrustStore.jks -storepass storepass
回车后看到提示
- 同理,将服务端公钥导入到客户端TrustStore中
keytool -import -alias serverpublickey -file Server_PublicCert.cer -keystore Client_TrustStore.jks -storepass storepass
同样,出现提示,输入y,回车即可
为了方便复制,把所有的一起贴出来
keytool -genkey -alias clientprivatekey -keypass keypass -keystore Client_KeyStore.jks -storepass storepass -dname "CN=tongtech.com,C=CN" -keyalg RSA
keytool -selfcert -keystore Client_KeyStore.jks -storepass storepass -alias clientprivatekey -keypass keypass
keytool -export -alias clientprivatekey -file Client_PublicCert.cer -keystore Client_KeyStore.jks -storepass storepass
keytool -genkey -aliasserverprivatekey -keypass keypass -keystore Server_KeyStore.jks -storepass storepass -dname "CN=tongtech.com,C=CN" -keyalg RSA
keytool -selfcert -keystore Server_KeyStore.jks -storepass storepass -aliasserverprivatekey -keypass keypass
keytool -export -aliasserverprivatekey -file Server_PublicCert.cer -keystore Server_KeyStore.jks -storepass storepass
keytool -import -aliasclientpublickey -file Client_PublicCert.cer -keystore Server_TrustStore.jks -storepass storepass
keytool -import -alias serverpublickey -file Server_PublicCert.cer -keystore Client_TrustStore.jks -storepass storepass
最后,在"C:\Users\CYX" (根据实际情况)目录下会有这几个文件
只要后缀是'.jks'的文件,通过名字就能看出哪些是客户端哪些是服务端。
服务端实现
服务端代码结构图
package com.cxf.security.server.inter; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebService; @WebService public interface HelloService { @WebMethod public String sayHello(@WebParam(name = "message") String message); }接口实现类
package com.cxf.security.server.impl; import com.cxf.security.server.inter.HelloService; public class HelloServiceImpl implements HelloService { @Override public String sayHello(String message) { System.out.println("服务端接收消息 : " + message); return "Hi : " + message; } }Sericuty回调函数
package com.cxf.security.server.callback; import java.io.IOException; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import org.apache.ws.security.WSPasswordCallback; public class UTPasswordServerCallBack implements CallbackHandler { @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; pc.setPassword("keypass"); System.out.println("Server Identifier=" + pc.getIdentifier()); System.out.println("Server Password=" + pc.getPassword()); } }
密钥的配置文件
Server_Decrypt.properties
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin org.apache.ws.security.crypto.merlin.keystore.type=jks org.apache.ws.security.crypto.merlin.keystore.password=storepass org.apache.ws.security.crypto.merlin.keystore.alias=serverprivatekey org.apache.ws.security.crypto.merlin.file=com/cxf/security/server/cert/Server_KeyStore.jksServer_SignVerf.properties
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin org.apache.ws.security.crypto.merlin.keystore.type=jks org.apache.ws.security.crypto.merlin.keystore.password=storepass org.apache.ws.security.crypto.merlin.keystore.alias=clientpublickey org.apache.ws.security.crypto.merlin.file=com/cxf/security/server/cert/Server_TrustStore.jks服务端主方法
package com.cxf.security.server; import java.util.HashMap; import java.util.Map; import javax.xml.ws.Endpoint; import org.apache.cxf.jaxws.EndpointImpl; import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor; import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; import org.apache.ws.security.handler.WSHandlerConstants; import com.cxf.security.server.callback.UTPasswordServerCallBack; import com.cxf.security.server.impl.HelloServiceImpl; public class CXFServer { private static final String ADDRESS = "http://localhost:8088/security/helloservice"; public static void main(String[] args) { EndpointImpl ep = (EndpointImpl) Endpoint.publish(ADDRESS, new HelloServiceImpl()); org.apache.cxf.endpoint.Endpoint cxfEp = ep.getServer().getEndpoint(); Map<String, Object> inProp = new HashMap<String, Object>(); inProp.put(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.ENCRYPT); inProp.put(WSHandlerConstants.PW_CALLBACK_CLASS, UTPasswordServerCallBack.class.getName()); inProp.put(WSHandlerConstants.SIG_PROP_FILE, "com/cxf/security/server/cert/Server_SignVerf.properties"); inProp.put(WSHandlerConstants.DEC_PROP_FILE, "com/cxf/security/server/cert/Server_Decrypt.properties"); cxfEp.getInInterceptors().add(new WSS4JInInterceptor(inProp)); Map<String, Object> outProp = new HashMap<String, Object>(); outProp.put(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.ENCRYPT); outProp.put(WSHandlerConstants.USER, "serverprivatekey"); outProp.put(WSHandlerConstants.PW_CALLBACK_CLASS, UTPasswordServerCallBack.class.getName()); outProp.put(WSHandlerConstants.ENCRYPTION_USER, "clientpublickey"); outProp.put(WSHandlerConstants.SIG_PROP_FILE, "com/cxf/security/server/cert/Server_Decrypt.properties");// 私钥 outProp.put(WSHandlerConstants.ENC_PROP_FILE, "com/cxf/security/server/cert/Server_SignVerf.properties");// 公钥 cxfEp.getOutInterceptors().add(new WSS4JOutInterceptor(outProp)); System.out.println("CXF Running , address : " + ADDRESS); } }
注意上面标红的参数!!!
然后启动服务端,发布服务。
客户端实现
客户端代码结构图
红框是CXF自动生成的代码,如何生成,不再多少,看之前WebService的文章。
回调函数
package com.cxf.security.callback; import java.io.IOException; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import org.apache.ws.security.WSPasswordCallback; public class UTPasswordClientCallBack implements CallbackHandler { @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; pc.setPassword("keypass"); System.out.println("Client Identifier=" + pc.getIdentifier()); System.out.println("Client Password=" + pc.getPassword()); } }
密钥配置文件
Client_Encrypt.properties
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin org.apache.ws.security.crypto.merlin.keystore.type=jks org.apache.ws.security.crypto.merlin.keystore.password=storepass org.apache.ws.security.crypto.merlin.keystore.alias=serverpublickey org.apache.ws.security.crypto.merlin.file=com/cxf/security/cert/Client_TrustStore.jks
Client_Sign.properties
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin org.apache.ws.security.crypto.merlin.keystore.type=jks org.apache.ws.security.crypto.merlin.keystore.password=storepass org.apache.ws.security.crypto.merlin.keystore.alias=clientprivatekey org.apache.ws.security.crypto.merlin.file=com/cxf/security/cert/Client_KeyStore.jks
客户端主程序
package com.cxf.security.client; import java.util.HashMap; import java.util.Map; import org.apache.cxf.endpoint.Endpoint; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor; import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; import org.apache.ws.security.handler.WSHandlerConstants; import com.cxf.security.callback.UTPasswordClientCallBack; import com.cxf.security.server.impl.HelloServiceImplService; import com.cxf.security.server.inter.HelloService; public class CXFClient { public static void main(String[] args) { HelloServiceImplService ss = new HelloServiceImplService(); HelloService service = ss.getHelloServiceImplPort(); org.apache.cxf.endpoint.Client client = ClientProxy.getClient(service); Endpoint cxfEp = client.getEndpoint(); // Clint Out Map<String, Object> outProp = new HashMap<String, Object>(); outProp.put(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.ENCRYPT); outProp.put(WSHandlerConstants.USER, "clientprivatekey"); outProp.put(WSHandlerConstants.ENCRYPTION_USER, "serverpublickey"); outProp.put(WSHandlerConstants.PW_CALLBACK_CLASS, UTPasswordClientCallBack.class.getName()); outProp.put(WSHandlerConstants.SIG_PROP_FILE, "com/cxf/security/cert/Client_Sign.properties"); outProp.put(WSHandlerConstants.ENC_PROP_FILE, "com/cxf/security/cert/Client_Encrypt.properties"); cxfEp.getOutInterceptors().add(new WSS4JOutInterceptor(outProp)); // Client In(Return) Map<String, Object> inProp = new HashMap<String, Object>(); inProp.put(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.ENCRYPT); inProp.put(WSHandlerConstants.PW_CALLBACK_CLASS, UTPasswordClientCallBack.class.getName()); inProp.put(WSHandlerConstants.DEC_PROP_FILE, "com/cxf/security/cert/Client_Sign.properties"); inProp.put(WSHandlerConstants.SIG_PROP_FILE, "com/cxf/security/cert/Client_Encrypt.properties"); cxfEp.getInInterceptors().add(new WSS4JInInterceptor(inProp)); String result = service.sayHello("CYX"); System.out.println(result); } }
服务端发布之后,WSDL文档
服务端接收消息
客户端接收到的消息
如果你之前使用过CXF并在里面加入拦截器,你会发现,服务端和客户端发送的消息都是明文发送,毫无安全性。
现在,让我们在服务端和客户端主程序中加入CXF拦截器,再看看发送消息的详细信息
服务端代码
package com.cxf.security.server; import java.util.HashMap; import java.util.Map; import javax.xml.ws.Endpoint; import org.apache.cxf.interceptor.LoggingInInterceptor; import org.apache.cxf.jaxws.EndpointImpl; import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor; import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; import org.apache.ws.security.handler.WSHandlerConstants; import com.cxf.security.server.callback.UTPasswordServerCallBack; import com.cxf.security.server.impl.HelloServiceImpl; public class CXFServer { private static final String ADDRESS = "http://localhost:8088/security/helloservice"; public static void main(String[] args) { EndpointImpl ep = (EndpointImpl) Endpoint.publish(ADDRESS, new HelloServiceImpl()); org.apache.cxf.endpoint.Endpoint cxfEp = ep.getServer().getEndpoint(); Map<String, Object> inProp = new HashMap<String, Object>(); inProp.put(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.ENCRYPT); inProp.put(WSHandlerConstants.PW_CALLBACK_CLASS, UTPasswordServerCallBack.class.getName()); inProp.put(WSHandlerConstants.SIG_PROP_FILE, "com/cxf/security/server/cert/Server_SignVerf.properties"); inProp.put(WSHandlerConstants.DEC_PROP_FILE, "com/cxf/security/server/cert/Server_Decrypt.properties"); cxfEp.getInInterceptors().add(new WSS4JInInterceptor(inProp)); Map<String, Object> outProp = new HashMap<String, Object>(); outProp.put(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.ENCRYPT); outProp.put(WSHandlerConstants.USER, "serverprivatekey"); outProp.put(WSHandlerConstants.PW_CALLBACK_CLASS, UTPasswordServerCallBack.class.getName()); outProp.put(WSHandlerConstants.ENCRYPTION_USER, "clientpublickey"); outProp.put(WSHandlerConstants.SIG_PROP_FILE, "com/cxf/security/server/cert/Server_Decrypt.properties");// 私钥 outProp.put(WSHandlerConstants.ENC_PROP_FILE, "com/cxf/security/server/cert/Server_SignVerf.properties");// 公钥 cxfEp.getOutInterceptors().add(new WSS4JOutInterceptor(outProp)); cxfEp.getInInterceptors().add(new LoggingInInterceptor()); cxfEp.getInInterceptors().add(new LoggingInInterceptor()); System.out.println("CXF Running , address : " + ADDRESS); } }
客户端代码
package com.cxf.security.client; import java.util.HashMap; import java.util.Map; import org.apache.cxf.endpoint.Endpoint; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.interceptor.LoggingInInterceptor; import org.apache.cxf.interceptor.LoggingOutInterceptor; import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor; import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; import org.apache.ws.security.handler.WSHandlerConstants; import com.cxf.security.callback.UTPasswordClientCallBack; import com.cxf.security.server.impl.HelloServiceImplService; import com.cxf.security.server.inter.HelloService; public class CXFClient { public static void main(String[] args) { HelloServiceImplService ss = new HelloServiceImplService(); HelloService service = ss.getHelloServiceImplPort(); org.apache.cxf.endpoint.Client client = ClientProxy.getClient(service); Endpoint cxfEp = client.getEndpoint(); // Clint Out Map<String, Object> outProp = new HashMap<String, Object>(); outProp.put(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.ENCRYPT); outProp.put(WSHandlerConstants.USER, "clientprivatekey"); outProp.put(WSHandlerConstants.ENCRYPTION_USER, "serverpublickey"); outProp.put(WSHandlerConstants.PW_CALLBACK_CLASS, UTPasswordClientCallBack.class.getName()); outProp.put(WSHandlerConstants.SIG_PROP_FILE, "com/cxf/security/cert/Client_Sign.properties"); outProp.put(WSHandlerConstants.ENC_PROP_FILE, "com/cxf/security/cert/Client_Encrypt.properties"); cxfEp.getOutInterceptors().add(new WSS4JOutInterceptor(outProp)); // Client In(Return) Map<String, Object> inProp = new HashMap<String, Object>(); inProp.put(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.ENCRYPT); inProp.put(WSHandlerConstants.PW_CALLBACK_CLASS, UTPasswordClientCallBack.class.getName()); inProp.put(WSHandlerConstants.DEC_PROP_FILE, "com/cxf/security/cert/Client_Sign.properties"); inProp.put(WSHandlerConstants.SIG_PROP_FILE, "com/cxf/security/cert/Client_Encrypt.properties"); cxfEp.getInInterceptors().add(new WSS4JInInterceptor(inProp)); client.getInInterceptors().add(new LoggingInInterceptor()); client.getOutInterceptors().add(new LoggingOutInterceptor()); String result = service.sayHello("CYX"); System.out.println(result); } }
然后在启动执行一次
服务端接收的打印消息
四月 09, 2017 10:28:32 下午 org.apache.cxf.services.HelloServiceImplService.HelloServiceImplPort.HelloService 信息: Inbound Message ---------------------------- ID: 1 Address: http://localhost:8088/security/helloservice?wsdl Encoding: UTF-8 Http-Method: GET Content-Type: text/xml Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], content-type=[text/xml], Host=[localhost:8088], Pragma=[no-cache], User-Agent=[Apache CXF 2.5.9]} -------------------------------------- 四月 09, 2017 10:28:32 下午 org.apache.cxf.services.HelloServiceImplService.HelloServiceImplPort.HelloService 信息: Inbound Message ---------------------------- ID: 2 Address: http://localhost:8088/security/helloservice?wsdl=HelloService.wsdl Encoding: UTF-8 Http-Method: GET Content-Type: text/xml Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], content-type=[text/xml], Host=[localhost:8088], Pragma=[no-cache], User-Agent=[Apache CXF 2.5.9]} -------------------------------------- 四月 09, 2017 10:28:34 下午 org.apache.cxf.services.HelloServiceImplService.HelloServiceImplPort.HelloService 信息: Inbound Message ---------------------------- ID: 3 Address: http://localhost:8088/security/helloservice Encoding: UTF-8 Http-Method: POST Content-Type: text/xml; charset=UTF-8 Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Length=[4086], content-type=[text/xml; charset=UTF-8], Host=[localhost:8088], Pragma=[no-cache], SOAPAction=[""], User-Agent=[Apache CXF 2.5.9]} Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="1"><xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="EK-33CAF81E824A212A8914917481147674"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><wsse:SecurityTokenReference><ds:X509Data><ds:X509IssuerSerial><ds:X509IssuerName>CN=tongtech.com,C=CN</ds:X509IssuerName><ds:X509SerialNumber>728416868</ds:X509SerialNumber></ds:X509IssuerSerial></ds:X509Data></wsse:SecurityTokenReference></ds:KeyInfo><xenc:CipherData><xenc:CipherValue>qfuopESDELeHleE5qfzUUmZkx4UQd+EgBz3Rq3WTKYQKNDd/T61yihSB/hGa/DQKMfh9yANp28P04/taMzo4Qpo96Slo5B5d9TPIyTnNkkzKGAFefLJF9xp1Bmg2Vrfnm6M3qXPBcZWZktqyTkLdabR/IPZ6pyi11XpEK40ieMz3wjYk23OIxo7ced3Ni9zKeIKbHy16SnIXrPvFiisZ9jk4ewBZGyGTC4zGOVKLshsHkcExUIxriid2ZMXxqSQCgCD3JwCehjQpNJXWhtrvKt+ntlqM/sRCKUgpl/1nb5qrRU5jWy5WtPLS7CPlffVFdiew4QwJuvUVq4nb8BcuRQ==</xenc:CipherValue></xenc:CipherData><xenc:ReferenceList><xenc:DataReference URI="#ED-4"/></xenc:ReferenceList></xenc:EncryptedKey><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-3"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="soap"/></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><ds:Reference URI="#id-2"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList=""/></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>/wPhSBQs5xeDSv823rqKZylM8LU=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>ZBAgLNymg4fAZfbS40J45IVHhCjacRnWuG0jUbvzhi9Y4GMsKY1iJ4EVkwyGnjtQfqVx4v8jDoTlCIY9/VU7gEfN8l8HOBxUIw2d7R8z96mcs6Ph1kR7k4h6EmcT4tmlZK/9kfNcLH2XE/UA33AS5vHEAqVQpnoxJWS86ixn6ojWt3h8OGqHROQBYcqJG2FMvrQjpZ1/MXr5EOmx32F3PCFIATR/9716QI/BE4vaOxQcFHO3yUJX5AbQ0c16Nm+qWTLce8Jd0d14ZPNl5otQ4A6dQNlDdllzQQJOw0EhDV7cRMabqqeCJcuo//+1NFp/xmDnOkcAd3QXjPSCpuxFBQ==</ds:SignatureValue><ds:KeyInfo Id="KI-33CAF81E824A212A8914917481145212"><wsse:SecurityTokenReference wsu:Id="STR-33CAF81E824A212A8914917481145243"><ds:X509Data><ds:X509IssuerSerial><ds:X509IssuerName>CN=tongtech.com,C=CN</ds:X509IssuerName><ds:X509SerialNumber>77579749</ds:X509SerialNumber></ds:X509IssuerSerial></ds:X509Data></wsse:SecurityTokenReference></ds:KeyInfo></ds:Signature><wsu:Timestamp wsu:Id="TS-1"><wsu:Created>2017-04-09T14:28:34.486Z</wsu:Created><wsu:Expires>2017-04-09T14:33:34.486Z</wsu:Expires></wsu:Timestamp></wsse:Security></soap:Header><soap:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-2"><xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="ED-4" Type="http://www.w3.org/2001/04/xmlenc#Content"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey"><wsse:Reference URI="#EK-33CAF81E824A212A8914917481147674"/></wsse:SecurityTokenReference></ds:KeyInfo><xenc:CipherData><xenc:CipherValue>PtZLFUeV+wfRAVV5x+aaakbOFC/UcyKrC1ExH/Tlka76kc5Ib3E/3Hyp+oIIAWrBB7eVTzu1196tWbcodStbGUTxLmevIWKFvjtdeZfRew909JNN/NWEREjNre+pl5RECUkCM04HWSSm3y25OOdq5S2jfUg1aCTD7LONqUWhzuc=</xenc:CipherValue></xenc:CipherData></xenc:EncryptedData></soap:Body></soap:Envelope> -------------------------------------- log4j:WARN No appenders could be found for logger (org.apache.xml.security.Init). log4j:WARN Please initialize the log4j system properly. Server Identifier=serverprivatekey Server Password=keypass 服务端接收消息 : CYX Server Identifier=serverprivatekey Server Password=keypass
客户端打印的信息
SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/H:/Eclipse_Code/CXF/CXF_Client_Security_x509/lib/slf4j-jdk14-1.6.2.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/H:/Eclipse_Code/CXF/CXF_Client_Security_x509/lib/slf4j-log4j12-1.7.6.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. 四月 09, 2017 10:28:33 下午 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDL 信息: Creating Service {http://impl.server.security.cxf.com/}HelloServiceImplService from WSDL: http://localhost:8088/security/helloservice?wsdl log4j:WARN No appenders could be found for logger (org.apache.xml.security.Init). log4j:WARN Please initialize the log4j system properly. Client Identifier=clientprivatekey Client Password=keypass 四月 09, 2017 10:28:34 下午 org.apache.cxf.services.HelloServiceImplService.HelloServiceImplPort.HelloService 信息: Outbound Message --------------------------- ID: 1 Address: http://localhost:8088/security/helloservice Encoding: UTF-8 Content-Type: text/xml Headers: {Accept=[*/*], SOAPAction=[""]} Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="1"><xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="EK-33CAF81E824A212A8914917481147674"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><wsse:SecurityTokenReference><ds:X509Data><ds:X509IssuerSerial><ds:X509IssuerName>CN=tongtech.com,C=CN</ds:X509IssuerName><ds:X509SerialNumber>728416868</ds:X509SerialNumber></ds:X509IssuerSerial></ds:X509Data></wsse:SecurityTokenReference></ds:KeyInfo><xenc:CipherData><xenc:CipherValue>qfuopESDELeHleE5qfzUUmZkx4UQd+EgBz3Rq3WTKYQKNDd/T61yihSB/hGa/DQKMfh9yANp28P04/taMzo4Qpo96Slo5B5d9TPIyTnNkkzKGAFefLJF9xp1Bmg2Vrfnm6M3qXPBcZWZktqyTkLdabR/IPZ6pyi11XpEK40ieMz3wjYk23OIxo7ced3Ni9zKeIKbHy16SnIXrPvFiisZ9jk4ewBZGyGTC4zGOVKLshsHkcExUIxriid2ZMXxqSQCgCD3JwCehjQpNJXWhtrvKt+ntlqM/sRCKUgpl/1nb5qrRU5jWy5WtPLS7CPlffVFdiew4QwJuvUVq4nb8BcuRQ==</xenc:CipherValue></xenc:CipherData><xenc:ReferenceList><xenc:DataReference URI="#ED-4"/></xenc:ReferenceList></xenc:EncryptedKey><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-3"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="soap"/></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><ds:Reference URI="#id-2"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList=""/></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>/wPhSBQs5xeDSv823rqKZylM8LU=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>ZBAgLNymg4fAZfbS40J45IVHhCjacRnWuG0jUbvzhi9Y4GMsKY1iJ4EVkwyGnjtQfqVx4v8jDoTlCIY9/VU7gEfN8l8HOBxUIw2d7R8z96mcs6Ph1kR7k4h6EmcT4tmlZK/9kfNcLH2XE/UA33AS5vHEAqVQpnoxJWS86ixn6ojWt3h8OGqHROQBYcqJG2FMvrQjpZ1/MXr5EOmx32F3PCFIATR/9716QI/BE4vaOxQcFHO3yUJX5AbQ0c16Nm+qWTLce8Jd0d14ZPNl5otQ4A6dQNlDdllzQQJOw0EhDV7cRMabqqeCJcuo//+1NFp/xmDnOkcAd3QXjPSCpuxFBQ==</ds:SignatureValue><ds:KeyInfo Id="KI-33CAF81E824A212A8914917481145212"><wsse:SecurityTokenReference wsu:Id="STR-33CAF81E824A212A8914917481145243"><ds:X509Data><ds:X509IssuerSerial><ds:X509IssuerName>CN=tongtech.com,C=CN</ds:X509IssuerName><ds:X509SerialNumber>77579749</ds:X509SerialNumber></ds:X509IssuerSerial></ds:X509Data></wsse:SecurityTokenReference></ds:KeyInfo></ds:Signature><wsu:Timestamp wsu:Id="TS-1"><wsu:Created>2017-04-09T14:28:34.486Z</wsu:Created><wsu:Expires>2017-04-09T14:33:34.486Z</wsu:Expires></wsu:Timestamp></wsse:Security></soap:Header><soap:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-2"><xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="ED-4" Type="http://www.w3.org/2001/04/xmlenc#Content"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey"><wsse:Reference URI="#EK-33CAF81E824A212A8914917481147674"/></wsse:SecurityTokenReference></ds:KeyInfo><xenc:CipherData><xenc:CipherValue>PtZLFUeV+wfRAVV5x+aaakbOFC/UcyKrC1ExH/Tlka76kc5Ib3E/3Hyp+oIIAWrBB7eVTzu1196tWbcodStbGUTxLmevIWKFvjtdeZfRew909JNN/NWEREjNre+pl5RECUkCM04HWSSm3y25OOdq5S2jfUg1aCTD7LONqUWhzuc=</xenc:CipherValue></xenc:CipherData></xenc:EncryptedData></soap:Body></soap:Envelope> -------------------------------------- 四月 09, 2017 10:28:35 下午 org.apache.cxf.services.HelloServiceImplService.HelloServiceImplPort.HelloService 信息: Inbound Message ---------------------------- ID: 1 Response-Code: 200 Encoding: UTF-8 Content-Type: text/xml;charset=UTF-8 Headers: {Content-Length=[4106], content-type=[text/xml;charset=UTF-8], Server=[Jetty(7.5.4.v20111024)]} Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="1"><xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="EK-A7A647358089463ACE14917481159194"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><wsse:SecurityTokenReference><ds:X509Data><ds:X509IssuerSerial><ds:X509IssuerName>CN=tongtech.com,C=CN</ds:X509IssuerName><ds:X509SerialNumber>77579749</ds:X509SerialNumber></ds:X509IssuerSerial></ds:X509Data></wsse:SecurityTokenReference></ds:KeyInfo><xenc:CipherData><xenc:CipherValue>CoxciTUONCQlxKP6Wgdpo9J4aEAy+8BNVAf4yATpDiuOi67GskkX7CRGUx3D2lFSC7e/HwvQ/HJw20G+79J8D1j9YgdgQxjTtUhEnseYtcPPlUbJVMPqnTm58kOy8CRHc+aTeR7S7DOQElFYrId+JPO46Bnf7t2JS74266lPFXHDcj/j4dwuw77nK4LJmeQmhol1+O8eFtQTIIu7hjHyHBfW4vkaVs4UT7nslxq93m4GGPfYv/DJnGGzOcEBlZX76T/jjb5oqmXtiMKCyLEgOZaohocZyBA+hYoHGfHSo7pUsyG1Jo/ThWyFOqxYZcSkxda/0QQwfh6Yid/+NqG57w==</xenc:CipherValue></xenc:CipherData><xenc:ReferenceList><xenc:DataReference URI="#ED-4"/></xenc:ReferenceList></xenc:EncryptedKey><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-3"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="soap"/></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><ds:Reference URI="#id-2"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList=""/></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>EYP0DsA4OdS9/Mw8P13Ql0Y6pZY=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>jDFId2cqkEQnYSxlGdChFWveUXxNp4BIio/AR2SOnqtu+RwDiZMy2izQLNvR0UEufVeYiiG8Avw67v4DGGizrmrNQ7qBGOJeh4As68xzHOovq2CaCoOMwIV6VfN0uHmQAkHjr6WT5vjhPg6poADs10cedD9Jw+y1plLdYfwiJ/jevIiv8JkO47JC8pId2DMZDMj3Ts8vHZSPA9tU2gFIi1wjR9zG+qU0+znFZcNgWq2bzaeeDvoqXvX2srQIeuxcPUFi/3kgk/WgVw8/Ht2m12t41LxGNRlvFcKbK2fbxDjKAd9FKHAa+pm/F5d6qe1DJ77yAkORKebQUiv/kTCa9w==</ds:SignatureValue><ds:KeyInfo Id="KI-A7A647358089463ACE14917481158862"><wsse:SecurityTokenReference wsu:Id="STR-A7A647358089463ACE14917481158863"><ds:X509Data><ds:X509IssuerSerial><ds:X509IssuerName>CN=tongtech.com,C=CN</ds:X509IssuerName><ds:X509SerialNumber>728416868</ds:X509SerialNumber></ds:X509IssuerSerial></ds:X509Data></wsse:SecurityTokenReference></ds:KeyInfo></ds:Signature><wsu:Timestamp wsu:Id="TS-1"><wsu:Created>2017-04-09T14:28:35.878Z</wsu:Created><wsu:Expires>2017-04-09T14:33:35.878Z</wsu:Expires></wsu:Timestamp></wsse:Security></soap:Header><soap:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-2"><xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="ED-4" Type="http://www.w3.org/2001/04/xmlenc#Content"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey"><wsse:Reference URI="#EK-A7A647358089463ACE14917481159194"/></wsse:SecurityTokenReference></ds:KeyInfo><xenc:CipherData><xenc:CipherValue>WzRMoJiEQdSxtdsMB07au6AJTE8F4yYFAlHF0+QAiQbpHlb8Uu5TDnvUAWFKrSCBTtnWDR1BlqmR15SnxVuHcJnKdyZ7ZzJjPhMIEmuGaksbzpQ2B1tSSRFa9sRy4f6ARfeOEQVSW/2IblyCtqkiafqnwRJT29WreVmIhhK4nbyz8dubsixq5DhTORZb7td9</xenc:CipherValue></xenc:CipherData></xenc:EncryptedData></soap:Body></soap:Envelope> -------------------------------------- Client Identifier=clientprivatekey Client Password=keypass Hi : CYX
Body中的信息全部加密了....
这里我不再对非加密的进行对比,按照之前的拦截器那篇文章,动手写写看就知道了....