在SSL握手时,客户端需要知道服务端的证书,如果证书必须先存在客户端的KeyStore中,那挺麻烦的!
在SSL握手过程中,服务端的确会把证书发给客户端,客户端肯定能拿到!
开始一直想着,一次握手,即拿到证书,又用这个证书来握手,建立连接,后来发现几乎不可行!
决定第一次握手时,先把证书拿到,再进行第二次SSL正式握手!用WireShark来看,Chrome访问HTTPS的站点也是这样做的!
不废话,直接上可用的代码:
import org.apache.http.conn.ssl.SSLContexts; import javax.net.ssl.*; import java.security.KeyStore; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; /** * God Bless You! * Author: Li Pengpeng * Date: 2014-11-05 */ public class CertUtil { /** * 目的是加载 HTTPS服务器提供的证书(含公钥) * @param keyStore keyStore * @param host host * @param port port * @throws Exception */ public static void checkTrustKey(KeyStore keyStore, String host, int port) throws Exception { TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(keyStore); X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0]; SavingTrustManager tm = new SavingTrustManager(defaultTrustManager); SSLContext context = SSLContexts.custom().useTLS().loadTrustMaterial(keyStore).build(); context.init(null, new TrustManager[]{tm}, null); SSLSocketFactory factory = context.getSocketFactory(); SSLSocket socket = (SSLSocket) factory.createSocket(host, port); socket.setSoTimeout(10000); try { socket.startHandshake(); socket.close(); // handshake success, need not set Cert } catch (SSLException e) { X509Certificate[] chain = tm.chain; if (chain == null || chain.length == 0) { throw e; } // handshake fail, set Cert for (X509Certificate cert : chain) { keyStore.setCertificateEntry(host + "_" + cert.getSerialNumber(), cert); } } } private static class SavingTrustManager implements X509TrustManager { private final X509TrustManager tm; private X509Certificate[] chain; SavingTrustManager(X509TrustManager tm) { this.tm = tm; } public X509Certificate[] getAcceptedIssuers() { throw new UnsupportedOperationException(); } public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { throw new UnsupportedOperationException(); } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { this.chain = chain; tm.checkServerTrusted(chain, authType); } } }
相关推荐
C# SSL服务端连接及安装数字证书
利用openssl和curl库获取https证书
ssl客户端和服务端代码,用户vc++6.0实现,简单易懂
实现了数字证书的制作、SSL安全通讯、加解密操作等功能
在Windows系统中配置HTTPS的SSL证书在服务端TLS协议中启用TLS1.2,推荐配置:TLSv1 TLSv1.1 TLSv1.2,用于微信小程序报错。
域名SSL证书在线生成系统_SSL在线自签证书工具_免费SSL在线生成源码 源码没有后台没有数据库,源码简单便捷,上传到空间内即可使用,虚拟主机,vps...随时可以生成自己的域名证书,可以在宝塔后台添加ssl,测试正常!
SSL双向认证握手过程 非常详细
SSL握手过程实例分析
为了便于更好的认识和理解SSL 协议,这里着重介绍SSL 协议的握手协议。介绍SSL协议双向认证的具体过程。
android ssl证书验证
ssl的客户端和服务端源代码,和大家分享
boost 框架下基于 openssl的ssl DEMO 服务端。
注意,这个插件报告所有使用SHA-1签署的SSL证书链在2017年1月1日之后失效都是脆弱的。这与谷歌的SHA-1加密哈希算法的逐渐衰落相一致。 该工具主要用于弱哈希算法签名的SSL证书升级成sha256算法签名证书。
SSL证书安装并且包括Apache服务器安装ssl证书、iis服务器安装ssl证书、Nginx服务器安装ssl证书、Tomcat服务器安装证书
本地ssl证书生成工具
客户端与服务器SSL双向认证(客户端:java-服务端:java):详细的过程,注意事项,运行成功!
SSL握手协议的研究,安全技术分析,usbkey融入java JSSE案例
SSL交互和握手过程 SSL消息按如下顺序发送: 1.Client Hello 客户发送服务器信息,包括它所支持的密码组。密码组中有密码算法和钥匙大小; 2.Server Hello 服务器选择客户和服务器都支持的密码组到客户。 3....
易语言SSL双向认证源码,SSL双向认证,设置证书文件,连接,取Socket句柄,建立SSL连接,断开连接,取服务器IP,发送数据,取回数据,取消息类型,标记参数是否正确,取服务端SSL算法,服务端是否有证书,取服务端证书内容,启动...
Windows下Nginx配置SSL实现Https访问(包含证书生成)