了解Http协议之前,先看一下网络的四层模型吧
http是基于应用层的协议,A客户端 -----> B服务端。
用抓包工具Fiddler来抓取一个http请求
request
CONNECT www.baidu.com:443 HTTP/1.1
#方法 url/uri 协议版本号1.1
Host: www.baidu.com:443
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
A SSLv3-compatible ClientHello handshake was found. Fiddler extracted the parameters below.
Version: 3.3 (TLS/1.2)
Random: 46 CB B1 19 29 B9 58 3C A4 FF 65 8E A1 EF DA 52 1B D5 D6 6A 11 A7 A2 20 A8 35 C9 2A 6D A4 CD 83
"Time": 1983/8/30 17:05:10
SessionID: FF 2D CE DC B3 D7 F4 62 00 A8 8C 67 80 CB 35 1A 09 59 81 3C 42 03 7F 9A 35 EA 74 3E 48 72 C3 AB
Extensions:
grease (0xbaba) empty
renegotiation_info 00
server_name www.baidu.com
extended_master_secret empty
SessionTicket E2 52 AF D7 F1 9D 4F 33 92 03 19 5D 84 F2 43 91 FC 6D 6E 13 C7 75 02 CB 05 DC BE C8 23 87 DA 26 4A 4D 72 B8 5E 38 2F B5 4C EC CA 5E 97 CD 18 5C F8 D7 67 48 29 A9 03 82 DE 0C AD BE 04 62 02 19 95 26 63 32 E7 6F 5E 6A 8D 70 3B 27 76 68 84 63 D5 02 D9 78 DC 56 B0 11 D8 CA 1C 2A 3C 9A 64 A8 37 CA 24 FC FB 9D 3F BB 01 31 C5 F2 3D 54 D0 08 5B 97 AA 3C 3B 67 3D 8D 21 2D 62 A0 D6 8C 2D D5 E0 F8 6C 1F 83 F9 FF 24 FD 44 22 89 3F AC D0 5C 88 63 0B 3A 8A EE 14 55 C1 DC 63 13 00 4B 6F F2
signature_algs ecdsa_secp256r1_sha256, rsa_pss_rsae_sha256, rsa_pkcs1_sha256, ecdsa_secp384r1_sha384, rsa_pss_rsae_sha384, rsa_pkcs1_sha384, rsa_pss_rsae_sha512, rsa_pkcs1_sha512, rsa_pkcs1_sha1
status_request OCSP - Implicit Responder
SignedCertTimestamp (RFC6962) empty
ALPN h2, http/1.1
channel_id(GoogleDraft) empty
ec_point_formats uncompressed [0x0]
supported_groups grease [0xcaca], x25519 [0x1d], secp256r1 [0x17], secp384r1 [0x18]
grease (0x1a1a) 00
padding 120 null bytes
Ciphers:
[4A4A] Unrecognized cipher - See https://www.iana.org/assignments/tls-parameters/
[C02B] TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
[C02F] TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
[C02C] TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
[C030] TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
[CCA9] TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
[CCA8] TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
[C013] TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
[C014] TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
[009C] TLS_RSA_WITH_AES_128_GCM_SHA256
[009D] TLS_RSA_WITH_AES_256_GCM_SHA384
[002F] TLS_RSA_WITH_AES_128_CBC_SHA
[0035] TLS_RSA_WITH_AES_256_CBC_SHA
[000A] SSL_RSA_WITH_3DES_EDE_SHA
Compression:
[00] NO_COMPRESSION
response
HTTP/1.1 200 Connection Established
FiddlerGateway: Direct
StartTime: 21:48:23.052
Connection: close
EndTime: 21:49:23.235
ClientToServerBytes: 1870
ServerToClientBytes: 490
This is a CONNECT tunnel, through which encrypted HTTPS traffic flows.
To view the encrypted sessions inside this tunnel, enable the Tools > Options > HTTPS > Decrypt HTTPS traffic option.
A SSLv3-compatible ServerHello handshake was found. Fiddler extracted the parameters below.
Version: 3.3 (TLS/1.2)
SessionID: FF 2D CE DC B3 D7 F4 62 00 A8 8C 67 80 CB 35 1A 09 59 81 3C 42 03 7F 9A 35 EA 74 3E 48 72 C3 AB
Random: 5D E6 67 AA 3C 50 78 C0 2E 50 3B FA D6 80 D0 AC FC 85 E1 15 DE A5 00 D6 6F 76 AC 0D 27 82 88 D5
Cipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [0xC02F]
CompressionSuite: NO_COMPRESSION [0x00]
Extensions:
ALPN http/1.1
uri/url
url : http://localhost:8080/test/index.html?name=jiy
指定协议类型 (ftp/http)
localhost(host)
8080 (port端口号)
test/index.html (path资源路径)
name=jiy (查询字符串)
uri 统一资源标志符
总的来说 URI是用一个字符串来表示互联网上的某一个资源。URL表示资源的地点(互联网资源的所在位置)
方法
http发起的每个请求,都需要告诉服务器要执行什么动作,那么这个动作就是前面报文看到的【method】
GET : 一般用户客户端发送一个URI地址去获取服务端的资源 (不安全 请求参数有大小限制)
POST:一般用户客户端传输一个实体到服务端,让服务端去保存(数据安全,请求参数大小无限制)
PUT:向服务器发送数据,一般用户更新操作
HEAD:用于向服务端发送一个查询head信息。
DELETE:客户端发起一个Delete请求要求服务端删除某个数据
OPTIONS:查询指定URI支持的方法类型(get/post)
HTTP协议的特点
HTTP协议是无状态的,HTTP协议本身不会对请求和响应的通信状态做保存。
为了实现Http协议能够记录状态,引入了cookie技术。通过在请求和响应报文中写入Cookie信息来控制客户端状态,cookie会根据从服务器端发送的响应报文内的Set-Cookie的首部字段,通知客户端保存Cookie。当下次客户端再往服务器发送请求时,客户端会自动在请求报文中加入Cookie值后发送出去。
由于http协议都是明文的可以通过抓包工具获取信息,内容可能被监听。不验证通信双方的身份。无法验证报文的完整性,报文可能被篡改。引出了https协议
HTTPS
在TCP协议和HTTP协议中加入了一个 TLS加密层。
https简介
https是一种加密的超文本传输协议,和http在协议差异在于对数据传输过程中,https对数据做了完全加密。由于http协议或者https协议都是在TCP传输层之上,同时又是一个分层结构,所以在TCP传输层之上又增加了一层SSL/TLS安全层,用于构建加密通道。
https实现原理
首先一个客户端对服务端发送请求(http)
但是如何保证发送过去的消息不会被抓包或者篡改呢? 首先想到的是进行添加密钥。
同时给客户端和服务端添加了密钥A,这是全是保证了双方的通信安全,但是互联网世界不单单只有两个机器进行通信,会存在很多的机器进行同时通信。
当存在大量不同的客户端时,就会存在有不安全的因素,非法客户端获取密钥,然后对服务器的密钥进行解密。存在安全的隐患。 那么我们会想到一个想法,那给不同的客户端分配不同的密钥
此时每客户端直接的密钥是不同,就无法向上面的那样通过相同的密钥然后去解密其他客户端的信息。但是又出现了一个新的问题,服务端如何通知客户端要使用哪一种密钥? 由于服务端无法预置密钥到客户端,所以需要发起通信通知客户端使用那个密钥,但是网络通信并不安全,如果不法分子在通信过程中截取了通信消息,又会存在不安全因素。
那么对称加密不行,我们就想到非对称加密。 非对称加密存在 :公钥, 私钥。
客户端持有公钥,服务端持有公钥,服务端用私钥对客户端的公钥进行解密。好像解决了密钥协商问题。但是引发了一个问题,公钥客户端怎么拿?
如果通过请求像服务端获取公钥,就会存在被中间人把请求拦截,然后自治公私钥返回给客户端,以后客户端所有的信息都会被中间窃取。所以这种网络发送公钥的方式不行。
好像通过客户端和服务端怎么也处理不了这种棘手的情况,那么我们是不是会想到要找一个第三方的机构进行帮助呢。 服务器把公钥通过第三方机构进行非对称加密。第三方机构用自己的私钥对服务端的公钥进行加密(数字证书)。将加密好的公钥返回给服务端。服务端将加密后的数字证书再返回给客户端。
但是这也存在一些问题,客户端如何解密第三方机构加密的数据? 第三方机构如何把数字证书的私钥分发给大量的客户端,如果发送到中间不法分子又该怎么办呢?
可以在所有的客户端内部内置第三方机构公钥,但是引出了一个问题,由于每个客户端/服务端都能像第三方机构申请证书,那么如何确认服务端/客户端是否可信,如何确认服务端的身份?(验证证书的有效性)
第三方机构在生成数字证书时,会对当前的证书进行加密算法(MD5)生成一个证书编号。客户端拿到数字证书使用证书中摘要的算法和内置的公钥,对数字证书进行解密,解密之后生成的内容,来判断数字证书的签名 编号是否被篡改。
接下来看一下整体的一个流程图
之后所有的通信数据将由之前交互过程中生成一个 pre master secret/ client.random/server.random 通过算法得到session key ,作为后续交互过程中的对称密钥。
以上的推演过程 便是https实现的原理。大致思路便是这样的了。