《HTTP权威指南》学习笔记(七)—安全HTTP与HTTPS
来源:互联网 发布:mac qq能远程协助吗 编辑:程序博客网 时间:2024/05/22 13:50
安全HTTP
HTTPS是最流行的HTTP安全形式。
HTTPS方案的URL以https://
开头
使用HTTPS时,所有的HTTP请求和响应数据在发送到网络之前,都要进行加密。HTTPS在HTTP传输层下面提供了一个传输级的密码安全层(可使用SSL或TLS)
数字加密
对称密钥加密技术
编码和解码使用的密钥值一样(密钥k)
发送端和接收端共享相同的密钥k才能进行通信。
缺点:发送者和接收者在互相对话前,一定要有一个共享的保密密钥。
公开密钥加密技术
使用两个非对称密钥:一个对主机报文编码,另一个对主机报文解码。
编码密钥是公开的(所以叫公开密钥加密),解码密钥是保密的,只有接收端才能对报文进行解码。
RSA算法
公开密钥非对称加密系统的关键:
确保有人拥有下面所有的线索,也无法计算出保密的私有密钥
- 公开密钥(公开的,所有人都可获得)
- 一小片拦截下来的密文
- 一条报文和与之相关的密文
RSA算法就是一个满足所有这些条件的流行的公开密钥加密系统。
数字签名
数字签名(digital signing):用加密系统对报文进行签名,说明是谁编写的报文,以证明报文未被篡改过。
数字签名是附加在报文上的特殊加密校验码。
好处:
- 证明是作者编写了这条报文
- 防止报文被篡改
通过非对称公开密钥技术产生。只有所有者知道其私有密钥,可将私有密钥作为指纹使用。
数字证书
数字证书(certs)中包含由某个受信任组织担保的用户或公司的相关信息。
上图就是由DigiCert组织签发给Github的数字证书
上图是12306在Chrome浏览器上浏览,可看出虽然使用了HTTPS,但是是由不受信任的签发者签名的数字证书
用证书对服务器进行认证
通过HTTPS建立一个安全Web事务之后,浏览器自动获取所连接服务器的数字证书。
HTTPS 细节介绍
HTTPS概述
HTTPS就是安全的传输层上发送的HTTP。在安全层对报文进行加密。
HTTP安全层是通过SSL或TLS
实现的。
HTTP的URL由
http://
起始,默认端口80,HTTPS的默认端口是443。
建立安全传输
HTTP:客户端建立到服务器80端口的TCP连接,发送一条请求报文,接收一条响应报文,关闭连接。
HTTPS:客户端打开一条道服务器443端口的连接,建立TCP连接,客户端和服务器初始化SSL层,沟通加密参数,交换密钥。SSL初始化完成后,客户端就可将请求报文加密后发送给安全层。
SSL握手
发送加密的HTTP报文之前,客户端和服务器要进行一次SSL握手。
下面是我用Java代码实现的打开https://www.github.com和12306购票网站https://kyfw.12306.cn/otn/leftTicket/init的Demo代码:
import javax.net.ssl.*;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.Socket;import java.net.URL;import java.security.KeyManagementException;import java.security.NoSuchAlgorithmException;import java.security.PublicKey;import java.security.cert.Certificate;import java.security.cert.CertificateException;import java.security.cert.X509Certificate;/** * Created by JohnTsai on 16/2/23. */public class HTTPSDemo { /** * 必须先进行SSL握手,再打开HttpsURLConnection * http://stackoverflow.com/questions/9568100/exception-when-printing-the-server-certificate-details */ public static void openHttpsURL(String urlString) { TrustManager[] trustManagers = new TrustManager[]{ new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } } }; try { SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, trustManagers, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); } catch (NoSuchAlgorithmException | KeyManagementException e) { e.printStackTrace(); } URL url = null; try { url = new URL(urlString); //建立HTTPS connection HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.setDoInput(true); connection.setRequestMethod("GET"); connection.connect(); if(connection.getResponseCode()==200){ System.out.println(urlString+"打开成功"); } printHttpsConnCert(connection); printHttpsConn(connection); } catch (IOException e) { e.printStackTrace(); } } public static void printHttpsConnCert(HttpsURLConnection conn) { if (conn == null) return; try { //连接所使用的密码程序 String cipherSuite = conn.getCipherSuite(); //服务器端的证书链 Certificate[] serverCertificates = conn.getServerCertificates(); System.out.println("密码程序:" + cipherSuite); for (Certificate certificate : serverCertificates) { String type = certificate.getType(); PublicKey publicKey = certificate.getPublicKey(); System.out.println("证书类型:" + type + "\n" + "公钥算法:" + publicKey.getAlgorithm() + "\n" + "公钥:" + publicKey.getFormat()); } } catch (SSLPeerUnverifiedException e) { e.printStackTrace(); } } public static void printHttpsConn(HttpsURLConnection conn) { if (conn == null) return; try { BufferedReader br = new BufferedReader( new InputStreamReader(conn.getInputStream())); String output = ""; while (br.readLine() != null) { output += br.readLine(); } br.close(); System.out.println(conn.getURL().getHost() + "的内容\n" + output); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { openHttpsURL("https://www.github.com"); openHttpsURL("https://kyfw.12306.cn/otn/leftTicket/init"); }}
运行结果:
- 《HTTP权威指南》学习笔记(七)—安全HTTP与HTTPS
- 《HTTP权威指南》阅读笔记(七)
- 《HTTP权威指南》学习笔记(一)—HTTP概述
- 《HTTP权威指南》学习笔记(三)—HTTP报文
- http权威指南学习笔记(二)
- HTTP权威指南学习笔记
- HTTP权威指南学习笔记
- 《HTTP权威指南》学习笔记
- HTTP权威指南学习笔记
- 【HTTP权威指南】笔记之三,识别、认证与安全
- 《HTTP权威指南》学习笔记-HTTP报文
- 《HTTP权威指南》学习笔记(四)—连接管理
- 《HTTP权威指南》学习笔记(五)—Web服务器
- 《HTTP权威指南》学习笔记(六)—客户端识别与cookie机制
- http权威指南笔记
- HTTP权威指南 笔记
- HTTP权威指南笔记
- HTTP权威指南笔记
- 第十六周 项一(1) —插入排序之直接插入排序
- 更新到cocoapods1.1.1版本
- 第16周项目1-快速排序
- redis专题-9.Spring使用jedis调试单机redis以及集群redis
- 第13周项目3-Dijkstra算法的验证
- 《HTTP权威指南》学习笔记(七)—安全HTTP与HTTPS
- Spring AOP面向切面
- Android知识结构
- pip安装
- 第十四周 项目1-验证算法(3)二叉排序树
- 初始Linux系统——安装java
- 第十一周项目1-验证二叉树算法(3)
- 让edittext在activity起始的时候不自动获得焦点
- 第十五周项目一(6)堆排序