今天学了下非对称加密算法,视频介绍了Diffie-Hellman key Exchange(迪菲赫尔曼DH密钥交换协议)原理是离散对数难题,也就是例如42mod12可以很容易推出10,但是xmod12=10很难准确复原x=42,因为有很多种可能,且将模数p换为质数并放大到1024或2048位后,使用超级计算机暴力破解也需要花费宇宙的年龄才有机会推出原先定下的x是什么。
然后我认为这用于https的TLS,但是现代https1.2之后,也就是https1.3才开始强制使用的是ECDHE(椭圆曲线DH),然后ai简单介绍了TLS的四次握手过程,以及RAS和DH的应用。RAS只在https1.0/1.1中使用,并于https1.3废弃
普遍TLS过程:
客户端 服务器
│ │
│ ─────────────────── 1. Client Hello ───────────────────→ │
│ - 支持的TLS版本 (例如:TLS 1.2) │
│ - 客户端随机数 (ClientRandom) │
│ - 支持的密码套件列表 (例如:TLS_RSA_WITH_AES_256_GCM_SHA384) │
│ │
│ ←───────────────── 2. Server Hello ─────────────────── │
│ - 选择的TLS版本 │
│ - 服务器随机数 (ServerRandom) │
│ - 选择的密码套件 (例如:TLS_RSA_WITH_AES_256_GCM_SHA384) │
│ - 服务器证书 (包含服务器的RSA公钥) │
│ │
│ │
│🔑 生成 Pre-Master Secret │
│🔒 使用服务器公钥加密 Pre-Master Secret │
│ │
│ ───────────────── 3. Client Key Exchange ──────────────→ │
│ - 加密后的 Pre-Master Secret │
│ ───────────────── 4. Change Cipher Spec ───────────────→ │
│ ───────────────── 5. Finished (加密) ───────────────────→ │
│ │
│ 🔓 使用服务器私钥解密 Pre-Master Secret │
│ 🧮 计算会话密钥 (基于 Pre-Master Secret, ClientRandom, ServerRandom) │
│ │
│ ←──────────────── 6. Change Cipher Spec ──────────────── │
│ ←──────────────── 7. Finished (加密) ─────────────────── │
│ │
═══ 🔒 AES加密通信开始 ══════════════════════════════════════ 🔒 AES加密通信开始 ═══
理解过程中一些QA:
疑问一:预主密钥是要什么生成的呢?
RAS:客户端随机生成后用服务器公钥加密返回
ECDHE:双方知道对方临时公钥和自己临时私钥后可用ECDH算法协商得出,之后第三次通信不需要传输预主密钥,但是要多传客户端临时公钥
疑问二:随机数有什么用?
RAS:参与计算主密钥和会话密钥,防止重放攻击,且能增加密钥随机性,算是加熵,类似密码加密时加盐
ECDHE:不参与预主密钥计算,但参与主密钥生成过程
总结:
所有主密钥生成都需要PDK(预主密钥,服务端随机数,客户端随机数,所有握手信息)
疑问三:ECDHE中预主密钥就是会话秘钥吗?
非也,所有预主密钥都需要再PDK()变成主密钥再PDK(,所有握手信息)才得到会话秘钥
密钥派生链:
Pre-Master Secret
→Master Secret
→Session Keys
疑问四:为什么主密钥之后还一定要PDK才得出会话密钥呢?
1.增加随机性,这很明显多操作一次多层保险
2.用途分离,首先主密钥再会话断开前不会被销毁,所以想象一棵树,主密钥作为树根,经过PDK向下长出会话秘钥,然后会话秘钥专门用于会话加密。这样在需要其他密钥时加点东西再从主密钥PDK一个就好了,这就是密码学的密钥分离原则。
ECDHE 握手流程图
客户端 服务器
│ │
│ ─────────────────── 1. Client Hello ───────────────────→ │
│ - 支持的TLS版本 (例如:TLS 1.2, TLS 1.3) │
│ - 客户端随机数 (ClientRandom) │
│ - 支持的密码套件列表 (例如:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) │
│ - 支持的椭圆曲线列表 (例如:P-256, P-384) │
│ - 客户端ECDHE公钥 (KeyShare - 临时) [TLS 1.3 可能在此发送] │
│ │
│ ←───────────────── 2. Server Hello ─────────────────── │
│ - 选择的TLS版本 │
│ - 服务器随机数 (ServerRandom) │
│ - 选择的密码套件 (例如:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) │
│ - 服务器证书 (包含服务器的RSA或ECDSA公钥用于签名) │
│ - 服务器ECDHE公钥 (KeyShare - 临时) │
│ - 数字签名 (服务器用其私钥对部分握手消息和临时ECDHE公钥的签名) │
│ │
|🔑 生成客户端临时ECDHE密钥对 │
|🧮 计算共享密钥 (ECDH算法: 基于客户端临时私钥和服务器临时公钥) │
│ │
│ ───────────────── 3. Client Key Exchange ──────────────→ │
│ - (如果未在Client Hello中发送,则在此发送客户端临时ECDHE公钥) │
│ ───────────────── 4. Change Cipher Spec ───────────────→ │
│ ───────────────── 5. Finished (加密) ───────────────────→ │
│ │
│ 🔑 生成服务器临时ECDHE密钥对 │
│ 🧮 计算共享密钥 (ECDH算法: 基于服务器临时私钥和客户端临时公钥) │
│ │
│ ←──────────────── 6. Change Cipher Spec ──────────────── │
│ ←──────────────── 7. Finished (加密) ─────────────────── │
│ │
═══ 🔒 AES加密通信开始 ══════════════════════════════════════ 🔒 AES加密通信开始 ═══
第一次通信:Client Hello由客户端->服务器,服务器已经过tcp三次握手
- 密码套件列表
- 客户端随机数
- [TLS1.3可能在此发送客户端ECDHE临时公钥]
第二次通信:Server Hello + Certificate + Server Key Exchange
服务器 → 客户端
内容:
• Server Hello:服务器随机数 + 选择的密码套件
• Certificate:服务器证书(用于身份认证)
• Server Key Exchange:临时ECDHE公钥 + 签名
📝 这三个消息通常在一个TCP包中发送
第三次握手:Client Key Exchange + Change Cipher Spec + Finished
客户端 -> 服务器
内容:
- [ECDHE]: Client Key Exchange:如果之前第一次未返回,则返回客户端ECDHE临时公钥
- [RAS]:返回预主密钥;
• Change Cipher Spec:切换到加密模式
• Finished:加密的握手验证
第四次通信:Change Cipher Spec + Finished
服务器 → 客户端
内容:服务器的加密模式切换和握手验证
- finshed将握手信息和计算出的会话秘钥哈希,双端都要用PRF密码学函数核对,由服务端发起返回服务端的核对结果,与客户端同步核对结果信息,用于确定双端传递信息没有被篡改
总之,TLS前段用非对称加密都是为了传递后半段的对称加密AES的秘钥,之后两端就可以愉快地使用AES对称加密通信了。也是因为非对称加密比较耗时,普遍比对称加密慢10到100倍,所以数据传输用的对称加密。
实际应用中:HTTPS = 非对称加密协商密钥 + 对称加密传输数据,既安全又高效!
也就是所谓采用混合加密系统
ps1:
密码加盐就是可以用用户注册时输入的密码加随机数的字符串进行哈希后存在数据库中。就可以避免数据库明文存储密码,这个随机数就是盐(为各个用户设定的特定,也跟随用户id存在同一列数据库表中),哈希可以是直接调用sha256,update后digest即可
ps2:
TLS1.3提前了加密时机,因为强制使用ECDHE,所以直接在第一次客户端发起时发送客户端公钥,这样可以再第二次服务器回话时直接开始加密会话