TLS协议中PRF和TLS1.3中的HKDF
TLS 协议中 PRF 和 TLS 1.3 中的 HKDF
我的TLS实现,大家可以参考:https://github.com/mrpre/atls/
TLS 1.3协议详解:https://blog.csdn.net/mrpre/article/details/81532469
TLS 1.0/1.1/1.2协议中,使用了PRF算法进行 key derive。
TLS 1.3中使用了标准的HKDF来进行key derive。
这里大概先回顾一下 <= TLS 1.2 时密钥导出流程和PRF算法使用场景。
然后再说一下 TLS 1.3 中的HKDF 算法 流程。
PRF算法:
PRF算法可以生成指定长度的数据
PRF调用了P_HASH算法
所以 先说P_HASH
(1) P_HASH
RFC定义:
P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +HMAC_hash(secret, A(2) + seed) +HMAC_hash(secret, A(3) + seed) + ...
其中
A() 如下定义:A(0) = seedA(i) = HMAC_hash(secret, A(i-1))
所谓的P_HASH,其实具体点就是 P_SHA256、P_SHA1…等,所以P_HASH中HMAC具体使用的HASH算法依据的就是P_HASH的具体HASH算法。P_hash中计算HMAC_hash的次数,取决于想要的输出的长度。
P_HASH迭代调用HMAC,其实 实现并不复杂,一个大循环判断是当前结果否已经满足输出长度,在循环里,先算法A(x),然后再算HMAC_hash(secret, A(x) + seed)
所以PRF算法很简单。
(2)PRF
P_HASH说完,该说一下PRF了,上面说过PRF实际调用了 P_HASH,所以现在描述下PRF
TLS 1.0/1.1 中
r1 = P_MD5(...);
r2 = P_SHA1(...);
r = r1 xor r2
TLS 1.2中
P_SHA256(...)或者P_SHA384(...)(具体使用哪个依据握手协商的加密套件)
可见,TLS1.2中,PRF算法其实就是直接调用了P_HASH算法,而TLS 1.0/1.1调用了两次P_HASH,一次是MD5一次是SHA1,两次的结果进行亦或才是最后的结果。
PRF算法在TLS协议中的运用
TLS 协议中:
(1)
当计算主密钥(master secret
)时
sec 是 “master secret” + client_random + server_random
seed 是 pre_master_secret
输出是 master secret
,48字节
(2)
当计算对称密钥(key material
)时
sec 是 “key expansion” + server_random + client_random
seed 是 master secret
输出是key block
,输出字节长度根据加密算法而定。
key block
中的各个部分,就是实际加解密使用的key。
(3)
当计算finished时
sec 是 “client/server finished”
seed 是握手的hash值
输出是12字节的值。
HKDF
HKDF本身不复杂,但是 在 TLS1.3 中的应用就比较复杂了。
HKDF详细的Paper见该文:https://eprint.iacr.org/2010/264.pdf 但是我觉得没必要看,因为看不懂。
建议看下面2篇文章:
我的HKDF RFC翻译 https://blog.csdn.net/mrpre/article/details/79879392
我的HKDF 示例代码 https://blog.csdn.net/mrpre/article/details/79881184
HKDF 在 TLS1.3中的应用,先上 RFC 的 key derive 的图:
图1
0|vPSK -> HKDF-Extract = Early Secret|+-----> Derive-Secret(.,| "ext binder" || "res binder",| "")| = binder_key|+-----> Derive-Secret(., "c e traffic",| ClientHello)| = client_early_traffic_secret|+-----> Derive-Secret(., "e exp master",| ClientHello)| = early_exporter_master_secretvDerive-Secret(., "derived", "")|v
(EC)DHE -> HKDF-Extract = Handshake Secret|+-----> Derive-Secret(., "c hs traffic",| ClientHello...ServerHello)| = client_handshake_traffic_secret|+-----> Derive-Secret(., "s hs traffic",| ClientHello...ServerHello)| = server_handshake_traffic_secretvDerive-Secret(., "derived", "")|v0 -> HKDF-Extract = Master Secret|+-----> Derive-Secret(., "c ap traffic",| ClientHello...server Finished)| = client_application_traffic_secret_0|+-----> Derive-Secret(., "s ap traffic",| ClientHello...server Finished)| = server_application_traffic_secret_0|+-----> Derive-Secret(., "exp master",| ClientHello...server Finished)| = exporter_master_secret|+-----> Derive-Secret(., "res master",ClientHello...client Finished)= resumption_master_secret
说实话,这张图让我第一次对TLS协议产生了反感。
用到的函数
看似很复杂,但是捋一下其实不复杂。
上面出现2个函数
1:HKDF-Extract
,这个函数就是HKDF的extract,它的实现见我上面给的链接。
2:Derive-Secret
,这个要着重说一下
根据RFC的定义
Derive-Secret(Secret, Label, Messages)
= HKDF-Expand-Label(Secret, Label,Transcript-Hash(Messages), Hash.length)
而
HKDF-Expand-Label(Secret, Label, Context, Length)
= HKDF-Expand(Secret, HkdfLabel, Length)
所以
Derive-Secret(Secret, Label, Messages)
= HKDF-Expand(Secret, HkdfLabel, Hash.length)
struct {uint16 length = Length;opaque label<7..255> = "tls13 " + Label;opaque context<0..255> = Context;
} HkdfLabel;
其中
HkdfLabel = Hash.length(2 字节) + label_length(1字节) + "tls13 " + Label + Hash.length(1字节) + HASH(Messages)
也就是说Derive-Secret
就是HKDF的expand操作。
Derive-Secret
在OpenSSL中的实现是 tls13_hkdf_expand
函数。
至此我们可以总结出,上面这个流程图中,无非2个操作,HKDF的extract和HKDF的expand操作。
图解1 - 从上往下看
不考虑图1右侧的 Derive-Secret
, 那么流程图就变成了如下图2形式:
图2
0|vPSK -> HKDF-Extract = Early Secret||||vDerive-Secret(., "derived", "")|v
(EC)DHE -> HKDF-Extract = Handshake Secret|||||vDerive-Secret(., "derived", "")|v0 -> HKDF-Extract = Master Secret||||||
这个图正是 tls13_generate_secret
函数所干的事情,而这个函数被如下函数调用,
tls_psk_do_binder/ssl_derive
计算 early secret
tls13_generate_handshake_secret
计算 handshake secret
tls13_generate_master_secret
计算 master secret
正好印证了tls13_generate_secret
的作用。
注意:tls13_generate_secret
实际函数执行的是如图三这个流程
图三
Derive-Secret(., "derived", "")|vin secret -> HKDF-Extract = xxx|||
多次反复调用,就形成了图2。
psk
和0
生成 early secret
early secret
和pms
生成handshake secret
handshake secret
和0
生成master secret
图解2 - 从左往右看
计算出来的 early secret
、handshake secret
、master secret
并不会直接用来加密数据,完全可以理解为是为了计算秘钥key而产生的临时变量
。这些临时变量
需要按照 图1 中右侧的流程计算,生成的XXX_traffic_secret
( XXX_traffic_secret
被称之为basekey
),
然而XXX_traffic_secret
也不会用来加密。。。还需要按照RFC 7.3 节中描述的步骤:
[sender]_write_key = HKDF-Expand-Label(Secret, "key", "", key_length)
[sender]_write_iv = HKDF-Expand-Label(Secret, "iv" , "", iv_length)
其中 Secret
就是 XXX_traffic_secret
。而输出[sender]_write_key
和[sender]_write_iv
就是加密时实际使用的参数了 。
这个流程在 tls13_derive_key
以及 tls13_derive_iv
中实现 。
Finish key
HKDF导出的流程中,还会导出一个finished_key
。
finished 计算
HMAC( MD(all_handshake), finished_key)
而
finished_key = HKDF-Expand-Label(BaseKey, "finished", "", Hash.length)
BaseKey
就是 handshake_traffic_secret
TLS协议中PRF和TLS1.3中的HKDF相关推荐
- TLS协议中的握手协议
TLS 握手协议(handshake protocol) 握手是TLS协议中最精密复杂的部分.在这个过程中,通信双方协商连接参数(沟通双方各有什么加密算法,选择一个最合适的算法),并且完成身份验证.根 ...
- tshark 解析pcap中带TLS协议的数据包
tshark的简单用法参考:tshark解析本地pcap数据包提取五元组{src_ip,src_port,proto,dst_ip,dst_port}与时间戳,包长 详细用法:官方DOC 比如提取一个 ...
- SSL/TLS协议详解(中)——证书颁发机构
SSL/TLS协议详解(中)--证书颁发机构 本文翻译自:https://www.wst.space/ssl-part-3-certificate-authority/ 上一篇中,我们讨论了关于Dif ...
- SSL / TLS协议中数字签名与hash算法的联系
今天要为大家介绍的是哈希算法,在介绍SHA之前,只有了解什么是SHA,我们才清楚SSL证书如何使用哈希来形成数字签名.那么什么是哈希呢? HASH算法将任意长度的二进制值映射为较短的固定长度的二进制值 ...
- 9. PKI - 三种密钥交换算法详解(RSA DHE ECDHE)及他们在SSL/TLS协议中的应用
9. PKI - 三种密钥交换算法详解(RSA& DHE& ECDHE)及他们在SSL/TLS协议中的应用 RSA密钥交换算法 DHE密钥交换算法 ECDHE密钥交换算法 参考 密钥交 ...
- 蚂蚁区块链第9课 SSL/TLS工作原理及在蚂蚁BAAS中的应用
1,摘要 辉哥在学习蚂蚁BAAS系统时,发现了一堆证书或者公私钥名称,包括trustCa,ca.crt,client.crt,client.key,pub.txt,MyPKCS12.p12等等文件,不 ...
- SSL协议安全系列:PKI体系中的证书吊销
GoSSIP_SJTU · 2016/03/03 10:06 0x00 前言 在前面的章节我们讨论了部分SSL/TLS握手协议.记录协议中存在的安全问题,针对它们的攻击以及相应的加固方案.在SSL/T ...
- android设置tls版本,Android O移除HttpsURLConnection中不安全的TLS版本回退
原标题:Android O移除HttpsURLConnection中不安全的TLS版本回退 为提高安全性,在 Android O 中,已从 HttpsURLConnection 中移除不安全的 TLS ...
- vue-router 路由嵌套显示不出来_网络协议|OSI模型第三层网络层中的路由
的IP协议 OSI第二层中用以太网协议定义了信息传输单元,简称为帧,它长这个样子. 同样的在OSI第三层中,会用 IP 协议去定义信息传输单元,简称为数据包,它长这个样子. 实际上,最终在网络上传输的 ...
最新文章
- 【面试】如何进行自我介绍
- 2013年1月31号
- html怎么引入sass样式,[样式设置] 使用sass格式的方式
- 十四、汇编指令(存储、加法、减法、乘法、除法、跳转、子程序、if判断、中断)
- 数据告诉你,哪个省才是高考地狱模式?
- apache http server 停止工作_Tomcat9配置HTTP/2
- linux 解压 7z 乱码,7z-linux下解决中文名乱码的终极办法
- 龙芯 Linux usb,使用debirf制作龙芯2F的LiveUSB
- python 音乐相册_App Store 上的“魔力相册-音乐相册、视频电子相册制作工具”...
- 【数据库取证篇】阿里云RDS数据库简介
- java 迭代_java迭代是什么意思
- Win8.1 安装nltk及nltk_data数据
- Netty解决TCP粘包/拆包导致的半包读写问题
- wdcp v2.5.15 php版本,wdcp_v2.5.15(20150826) 如何开启 多 SSL 站点!
- 【IP代理】吐槽某大爷IP
- 3.后端学习JavaScript
- 计算机网络安全漏洞及防范措施论文,浅谈计算机网络安全漏洞及防范措施论文.doc...
- 联想rd服务器系统安装,联想RD430服务器安装Windows2008R2系统
- 2021年科技园区规划设计方案
- 章丘谋定大葱功能性-农业大健康·万祥军:不当村官当会长