HTTP HTTPS RSA
推荐阅读 小林coding HTTP篇
文章目录
- HTTP 80
- HTTP 响应码
- 1xx:信息性状态码(Informational)
- 2xx:成功状态码(Success)
- 3xx:重定向状态码(Redirection)
- 4xx:客户端错误(Client Error)
- 5xx:服务器错误(Server Error)
- 常见字段
- GET POST
- HTTP/1 /2 /3
- HTTPS 443
- 加密方式
- 混合加密
- 摘要算法 -> 数字签名
- 数字证书
- TLS 1.2 握手
- RSA 算法加密
- 过程:
- 原理:
- 为什么安全:
HTTP 80
超文本传输协议 HyperText Transfer Protocol
HTTP 响应码
1xx:信息性状态码(Informational)
表示请求已被接收,继续处理。
-
100 Continue:客户端应继续其请求。
-
101 Switching Protocols:服务器同意切换协议。
2xx:成功状态码(Success)
表示请求已成功被接收、理解并处理。
- 200 OK:请求成功。
- 201 Created:资源已成功创建,常用于 POST 请求。
- 204 No Content:请求成功,但无返回内容。
3xx:重定向状态码(Redirection)
客户端需要进一步操作才能完成请求。
- 301 Moved Permanently:永久重定向。
- 302 Found(或 Temporary Redirect):临时重定向。
- 304 Not Modified:资源未修改,可使用缓存。
4xx:客户端错误(Client Error)
请求包含错误,客户端需修改。
- 400 Bad Request:请求无效,服务器无法理解。
- 401 Unauthorized:未授权,需要认证。
- 403 Forbidden:禁止访问,即使认证也无权。
- 404 Not Found:资源不存在。
- 405 Method Not Allowed:请求方法不被允许。
5xx:服务器错误(Server Error)
服务器在处理请求时出错。
- 500 Internal Server Error:服务器内部错误。
- 502 Bad Gateway:网关或代理收到无效响应。
- 503 Service Unavailable:服务器暂时不可用(如超载或维护)。
- 504 Gateway Timeout:网关超时未收到上游服务器响应。
常见字段
-
Host: www.xxx.com 请求中指定对方域名
-
Content-Length: 1000 回应数据长度
-
Connection: Keep-Alive 长连接
-
Content-Type: text/heml; charset=utf-8 数据格式
(请求方可以指定格式: Accept: /) -
Content-Encoding: gzip 编码,即压缩方法
(Accept-Encoding: gzip, deflate)
GET POST
-
GET 的语义是从服务器获取指定的资源
安全且幂等,因为是只读,服务器数据是安全的,每次请求结果是相同的。 -
POST 的语义是根据请求负荷(报文body)对指定的资源做出处理
不幂等,会修改资源。
HTTP/1 /2 /3
HTTPS 443
HTTP 是明文传输,不安全。
HTTPS 在 HTTP层与TCP层之间添加了TLS协议(传输层安全性协议 Transport Layer Security)
TCP三次握手后还要进行 TLS 握手
安全套接层(Secure Sockets Layer,缩写作 SSL)
加密方式
以下几个结合,分别确保 消息加密,消息不被篡改,中间人无法伪造
混合加密
-
在通信建立前采用非对称加密的方式交换「会话秘钥」
RSA 算法 (非对称加密算法) -
在通信过程中全部使用对称加密的「会话秘钥」
摘要算法 -> 数字签名
用摘要算法(哈希函数)来计算出内容的哈希值
对方也对内容计算,比较两个哈希值。
通过「私钥加密,公钥解密」的方式,保证消息不会被冒充
(但是公钥仍可能是中间人冒充的 —— 中间人攻击 !)
数字证书
Certificate Authority 证书授权
浏览器内置证书!里面有公钥
客户端验证流程:
证书信任链的问题:
如百度证书,可能证书是中间证书签发的
不是根证书,就无法根据本地已有的根证书中的公钥去验证 证书是否可信,于是向 CA 请求该中间证书,直到根证书。
电脑系统内置的根证书:
TLS 1.2 握手
基于 RSA 算法的 TLS 握手过程(TLS 1.2 with RSA key exchange):
- ClientHello
客户端发起加密通信请求 【支持的TLS协议版本;加密用随机数;支持的加密算法】 - SeverHello
服务器回应客户端 【确认TLS版本;加密用随机数;确认使用的加密算法;服务器证书】 - 客户端回应
客户端先通过浏览器或操作系统内置的 CA 公钥,确认服务器的数字证书的真实性。
如果证书没有问题,客户端会从数字证书中取出服务器的公钥,然后使用它加密报文。
接着发送【 预主密钥 ;加密通信算法改变通知;客户端握手结束通知】,同时自己用前面两个随机数+预主密钥生成了本次通信用的公钥——会话密钥。 - 服务器的最后回应
服务器也通过同样的方式计算出会话密钥
也向客户端发送最后的信息:【加密通信算法改变通知;服务器握手结束通知】
之后通过 会话密钥 加密 HTTP 通信即可。
RSA 握手“不那么安全”
一旦服务器私钥泄露,历史通信就可以被解密(前向保密性差)
现在主流推荐使用的是 TLS 1.3 ECDHE(椭圆曲线 Diffie-Hellman Ephemeral),支持前向保密。
RSA 算法加密
需要先了解一些数论:
- 欧拉函数 φ ( n ) φ(n) φ(n) 表示小于等于 n 且与 n互质的正整数的个数。对质数而言就是 n-1
- 欧拉定理:对于任意两个互质的正整数 a, n , 有 a φ ( n ) ≡ 1 ( m o d n ) a^{φ(n)} ≡1\pmod n aφ(n)≡1(modn)
(≡ 是模意义下同余) - 费马小定理: 如果 p 是一个质数,a是一个整数且 a 与 p 互质,那么 a p − 1 ≡ 1 ( m o d p ) a^{p − 1} ≡ 1 \pmod p ap−1≡1(modp)
过程:
-
选择两个大质数 p , q p, q p,q
模数 n = p ∗ q n = p*q n=p∗q 作为我们的模数 -
n 的欧拉函数 φ ( n ) = ( p − 1 ) ( q − 1 ) φ (n) = (p-1)(q-1) φ(n)=(p−1)(q−1)
-
加密指数 e e e ,取数 e 与 φ (n) 互质
e 模逆元设为 d d d ,即 e d ≡ 1 ( m o d φ ( n ) ) ed ≡ 1 \pmod {φ(n)} ed≡1(modφ(n)) (逆元其实就是倒数,取模意义下的)
可得 ed 其实就是 k ∗ φ ( n ) + 1 k*φ(n) + 1 k∗φ(n)+1
-
加密明文 m :
密文 c = m e m o d n c = m^e \mod n c=memodn
可以看到就是对原数据求幂 -
解密:
m = c d m o d n m = c^d \mod n m=cdmodn
原理:
整个过程就是先求明文 m 的 e 次幂,然后求 m^e 的 d 次幂
( m e ) d ( m o d n ) ({m^{e}})^{d} \pmod n (me)d(modn)
即
m e d ( m o d n ) {m^{ed}} \pmod n med(modn)
而由上可知 ed = k*φ(n) + 1 ,以及 欧拉定理中 m^φ(n) 取模n后为 1
所以上述表达式最终取模后为 m 本身 ✅
为什么安全:
模数 n 是公开的, e 是加密指数可作为公钥。
但是推出解密指数,需要得出 φ (n) ,这需要选择出正确的质数 p, q 。
“大整数分解难题” 将一个大整数 n 分解成两个质数 p 和 q 是非常困难的
当 n 是一个 2048 位的大整数时,它的两个因数 p 和 q 也是大质数(每个约 1024 位),在现有技术和算法下,分解这样的大整数需要数十亿年