我们正在使用基于HTTPS的JAX-WS客户端来发送消息(由CXF支持,我认为它使用SSLSocket)。 如果远程证书不可信/无效,我们希望记录远程证书详细信息以及消息详细信息。
最初我希望我们能得到一个有用的异常,但堆栈跟踪中有趣的异常是内部的(比如sun.security.validator.ValidatorException和sun.security.provider.certpath.SunCertPathBuilderException),所以不应该这样做。真的被使用了,而且似乎没有拿着远程证书。
所以我的问题是,在我还有消息详细信息(JAX-WS调用之外)的级别上,获取证书最为整洁的方式是什么?
到目前为止,我最好的猜测是添加我自己的javax.net.ssl.X509TrustManager,它包装当前使用的那个,并将证书放在ThreadLocal上,调用者可以在最近接收它。它看起来不是很整洁,但到目前为止它似乎是最好的:)
非常感谢任何建议!
答案 0 :(得分:0)
重点是JSSE在您的问题中正在做并隐藏您正在寻找的所有内容。但幸运的是,CXF似乎允许一些定制。 我们的想法是使用您自己的实现自定义SSLSocketFactory(http://cxf.apache.org/docs/tls-configuration.html#TLSConfiguration-ClientTLSParameters),并且必须创建自己Sockets附带的HandshakeCompletedListener。这是最后一个将转储您要查找的信息的对象,我给出了一个实现示例:
class CustomHandshakeCompletedListener implements HandshakeCompletedListener {
private HandshakeCompletedEvent hce;
private String cipher;
private Certificate[] peerCertificates = null;
private Principal peerPrincipal = null;
public void handshakeCompleted(HandshakeCompletedEvent hce) {
this.hce = hce;
// only cipersuites different from DH_anon* will return a server certificate
if(!cipher.toLowerCase().contains("dh_anon")) {
try {
cipher = hce.getCipherSuite();
peerCertificates = hce.getPeerCertificates();
peerPrincipal = hce.getPeerPrincipal();
// do anything you want with these certificates and ciphersuite
}
catch(SSLPeerUnverifiedException spue) {
System.err.println("unexpected exception :");
spue.printStackTrace();
}
}
}
仍然有一些工作要实现你的目标,如果这条线索运作良好,请告诉我们。