HTTPS协议实例介绍讲解
HTTPS即基于SSL的HTTP协议,简单地说就是HTTP的安全版。依托SSL协议,HTTPS协议能够确保整个通信过程都是经过加密的,秘钥是随机产生,并且能够通过数字证书验证通信双方的身份,以此来保证信息安全。其中证书中包含了证书所代表一端的公钥,以及一些其所具有基本信息,如机构名称、证书所作用域、证书的数字签名等,通过数字签名能够校验证书的真实性。通信的内容使用对称加密的方式进行加密,通信两端约定好通信密码后,通过公钥对密码进行加密传输,只有该公钥对应的私钥,也就是通信的另一端能够解密获取通信密码,这样既保证了通信安全,也使加密性能和时间成本可控。
HTTPS既支持单向认证,也支持双向认证,所谓的单向认证即只校验服务端证书的有效性,而双向认证则表示既校验服务端证书的有效性,同时也需要校验客户端证书的有效性。大部分情况下我们并不需要用到客户端证书,很多用户甚至没有客户端证书,但是某
些特定的环境下,如大额交易支付的场景下,也需要对用户的客户端证书进行校验,以保证通信的安全。
1、SSL/TLS
SSL协议的优势在于它与应用层协议独立无关,高层的应用层协议如HTTP、SSH,FTP等等,能透明的建立于SSL协议之上,在应
用层通信之前就已经完成加密算法、通信秘钥的协商以及服务端及客户端的认证工作,在此之后所有应用层协议所传输的数据都会被加密,
从而保证通信的私密性。
SSL的继任者TLS协议,是基于SSL协议的通用化协议,同样位于应用层和传输层之间,正逐步接替SSL称为下一代网络安全协议。
SSL/TLS协议均可以分为两层:一层为记录协议,一层为握手协议。记录协议建立在可靠的传输协议之上,提供数据封装、加密
解密、数据压缩、数据校验等基本功能。握手协议建立在记录协议之上,在实际的数据传输开始前,进行加密算法的协商,通信秘钥的
交换,通信双方的认证等工作。
2、java开发
SSL握手协议十分复杂,对于并非密码学专家的普通开发人员来说,理解交互过程不容易。对于普通开发人员来说,他们关心的并
不是如何实现SSL/TLS协议,而是如何才能让他们的程序以最简单的方式接入SSL/TLS强大的安全保护功能。JSSE正是这样的一个工具。
JSSE是Sun公司为了解决互联网信息安全传输提出的一个解决方案,它实现了SSL和TSL协议,包含了数据加密、服务器验证、
消息完整性和客户端验证等技术。通过使用JSSE简介的API,可以在服务端和客户端之间通过SSL/TSL协议安全地传输数据。
首先生成客户端证书、服务端证书。信任证书的导出:由于客户端与服务端证书都是在下面的CA所颁发,因此只需要将下面的CA的根证书作为信任库,就可以对客户端、服务端证书进行识别。
服务端:
public static void main(String[] args) throws Exception { String serverKeyStoreFile = "c:\\_tmp\\catserver.keystore"; String serverKeyStorePwd = "catserverks"; String catServerKeyPwd = "catserver"; String serverTrustKeyStoreFile = "c:\\_tmp\\catservertrust.keystore"; String serverTrustKeyStorePwd = "catservertrustks"; KeyStore serverKeyStore = KeyStore.getInstance("JKS"); serverKeyStore.load(new FileInputStream(serverKeyStoreFile), serverKeyStorePwd.toCharArray()); KeyStore serverTrustKeyStore = KeyStore.getInstance("JKS"); serverTrustKeyStore.load(new FileInputStream(serverTrustKeyStoreFile), serverTrustKeyStorePwd.toCharArray()); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(serverKeyStore, catServerKeyPwd.toCharArray()); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(serverTrustKeyStore); SSLContext sslContext = SSLContext.getInstance("TLSv1"); sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); SSLServerSocketFactory sslServerSocketFactory = sslContext.getServerSocketFactory(); SSLServerSocket sslServerSocket = (SSLServerSocket) sslServerSocketFactory.createServerSocket(SERVER_PORT); sslServerSocket.setNeedClientAuth(true); while (true) { SSLSocket s = (SSLSocket)sslServerSocket.accept(); CatServer cs = new CatServer(s); s.addHandshakeCompletedListener(cs); new Thread(cs).start(); } }
客户端:
public static void main(String[] args) throws Exception { String clientKeyStoreFile = "c:\\_tmp\\foxclient.keystore"; String clientKeyStorePwd = "foxclientks"; String foxclientKeyPwd = "foxclient"; String clientTrustKeyStoreFile = "c:\\_tmp\\foxclienttrust.keystore"; String clientTrustKeyStorePwd = "foxclienttrustks"; KeyStore clientKeyStore = KeyStore.getInstance("JKS"); clientKeyStore.load(new FileInputStream(clientKeyStoreFile), clientKeyStorePwd.toCharArray()); KeyStore clientTrustKeyStore = KeyStore.getInstance("JKS"); clientTrustKeyStore.load(new FileInputStream(clientTrustKeyStoreFile), clientTrustKeyStorePwd.toCharArray()); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(clientKeyStore, foxclientKeyPwd.toCharArray()); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(clientTrustKeyStore); SSLContext sslContext = SSLContext.getInstance("TLSv1"); sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); SSLSocketFactory socketFactory = sslContext.getSocketFactory(); Socket socket = socketFactory.createSocket("localhost", CatServer.SERVER_PORT); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); send("hello", out); send("exit", out); receive(in); socket.close(); }
3、部署HTTPS Web
tomcat单向认证配置:
编辑conf\server.xml文件,取消注释的HTTPS配置这一行。由于使用的keystore为PKCS#12格式,因此需要加参数
keystoreType=“pkcs12”,由于这里配置的是单向认证,只需要校验服务端证书的有效性,所有将clientAuth一项设置为false。
tomcat双向认证的配置:
相比较单向认证的配置,双向认证需要在其基础上进行些修改:
tomcat的server.xml文件增加信任库配置,truststoreFile指的是信任库地址,通过信任库中的根证书,服务端才能够对根证书签名的客户端进行识别。truststorePass指的是信任库的秘钥,truststoreType指的是信任库的格式,并且启用客户端认证,将
clientAuth设置为true。
在浏览器导入包含客户端证书与私钥的keystore文件。