代码角度看SSL握手过程

2022-03-08 0 2,976

名词解释:密码套件–SSL握手过程联合使用了一系列加密&摘要算法,这样一组算法的集合,称为密码套件。

以下调试信息输出代码为:
https://github.com/DeDf/atls — windows
fork自
https://github.com/mrpre/atls — linux

测试方法:
编译运行运行atls;
下载安装openssl,openssl s_client -connect 127.0.0.1:44444;
用wireshark抓loopback包,过滤条件是tls;

(SSL服务器视角)
a_tls_handshake[1]: a_tls_get_client_hello()
a_tls_handshake[2]: a_tls_send_srv_hello()
a_tls_handshake[8]: a_tls_send_srv_cert()
a_tls_handshake[3]: a_tls_send_srv_ke() Key Exchange
a_tls_handshake[4]: a_tls_send_srv_hello_done()
a_tls_handshake[12]: a_tls_get_client_ke() Key Exchange
a_tls_handshake[11]: a_tls_get_client_ccs() Change Cipher Spec
a_tls_handshake[14]: a_tls_get_client_finished()
a_tls_handshake[6]: a_tls_send_srv_ticket()
a_tls_handshake[5]: a_tls_send_srv_ccs() Change Cipher Spec
a_tls_handshake[10]: a_tls_send_srv_finished()

a_tls_get_client_hello()
这里有个两个重要信息,和一些扩展信息
1.重要的是Client random(32 Bytes),
2.重要的是支持的加密套件list
扩展信息里给出了
1.说明了client支持的椭圆曲线list
2.支持的hash与sign算法的list;sigalg_pair_t g_sigalg_pair[A_TLS_MAX_SIG_ALG]

a_tls_send_srv_hello()
1重要的是Server random(32 Bytes),
2服务器检查client支持的密码套件组,如果服务器支持,则从中选则一个返回给client,
本文以ECDHE_RSA_WITH_AES_128_GCM_SHA256为例

1
2
ECDH  - Elliptic Curve Diffie–Hellman key exchange - 椭圆曲线迪菲-赫尔曼密钥交换
ECDHE - (ECDH Ephemeral) 临时ECDH - 保证前向安全

a_tls_send_srv_cert()
服务器把自己的证书(链)发给client

a_tls_send_srv_ke()
服务器用ECDHE算法,选择一个server支持的椭圆曲线,本例为已命名的椭圆曲线,secp256r1,
注意client hello的扩展里可能说明了client支持的椭圆曲线list
用该椭圆曲线,生成一个65bytes的公钥;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
这里选择用client_hello里说明的hash与sign算法,rsa_pss_rsae_sha256 : 0x0804;
 hash算法为sha256;
  client random 32bytes + server  random 32bytes + 1 + 2 + 1 + ECDH 公钥 65bytes,
  上面共0x85字节过一次hash;
  接着是对上面hash的结果做rsa_pss_padding;
    有一个等于当前RSA密钥长度的buf(0x100字节),内容清0,密钥长度是证书决定的;
    生成一个hashlen(0x20字节)的随机数作为salt;
    buf - 1 - 0x20*2 - 1处一字节存一个"1",后面20字节存这个salt;
    0x00 * 8 (8字节) + 上次hash结果(0x20字节)+ salt(0x20字节),再来一次hash;
    这个hash挨着上面的salt存。
      然后进入mgf1算法(掩码生成函数),
      {
        用上面最后的hash值(0x20字节),加一个count(4字节 大端序),count从0开始计数;
        循环(count++)给这0x20+count4字节做hash,用这个hash,与buf[i]处异或填充buf[i],i从0到HashLen.
        也就是每做一次hash填32个字节(HashLen == 0x20字节);
        填充范围是上面的buf从头到(buf+0x100-HashLen-1)处;
        最后不到20字节的,按实际剩余字节数填充。
        buf最后一个字节置0xbc,首字节out[0] &= 0xFF >> 1;
      }
      mgf1算法结束,拼出buf(0x100字节:RSA密钥长度);
  然后 RSA_private_encrypt(0x100, buf(0x100字节), out, rsa, RSA_NO_PADDING) 生成的out也是0x100字节;
  这0x100个字节就是RSA sign的内容;

a_tls_send_srv_hello_done()
简单(略)

a_tls_get_client_ke()
收到client的ECDH的公钥65字节,算出pms 0x20字节,
用”master secret”13字节,+ client_random 0x20字节,+ srv_random 0x20字节,共0x4d字节;
与pms 0x20字节一起,经过phash算法(内部调用HMAC算法(参数调用sha256,一种标准的hash加盐算法)),算出48字节的master_Key.

a_tls_get_client_ccs()
用””key expansion”13字节,+ srv_random 0x20字节,+ client_random 0x20字节,共0x4d字节;
与master_Key 0x30字节一起,经过phash算法(内部调用HMAC算法(参数调用sha256,一种标准的hash加盐算法)),算出0x68字节的Key_Block;
Key_Block包含读与写的cipher_key 0x10字节,IV 4字节。
a_tls_init_cipher,用Key_Block各部分(读的cipher_key 0x10字节,IV 4字节)初始化对称解密算法(AES_128_GCM);
这里初始化的是读取client消息的对称解密算法。

a_tls_get_client_finished()
第一次收到被对称加密的数据,具体解密方式(AES_128_GCM)为以前写的demo的解密算法,不再叙述;
解出来的值为,当前所有接收和发送的握手(数据类型为 HANDHSHAKE = 0x16)数据(除当前的finished消息外),经过一次sha256得到一个hash值,
“client finished” 15个字节, + 上面hash值 0x20个字节,与MASTER_KEY(48 字节)一起;
经过phash算法(内部调用HMAC算法(参数调用sha256,一种标准的hash加盐算法)),得到12字节的值,
这个值就是client发来的值,不一致的话说明被篡改;

a_tls_send_srv_ticket()
atls这里只是简单实现,不是标准;

a_tls_send_srv_ccs() Change Cipher Spec
a_tls_init_cipher,用Key_Block各部分(写的cipher_key 0x10字节,IV 4字节)初始化对称解密算法(AES_128_GCM);
这里初始化的是server发送消息的对称加密算法。

a_tls_send_srv_finished()
第一次发送被对称加密的数据;
当前所有接收和发送的握手(数据类型为 HANDHSHAKE = 0x16)数据(除当前的finished消息外),经过一次sha256得到一个hash值,
“server finished” 15个字节, + 上面hash值 0x20个字节,与MASTER_KEY(48 字节)一起;
经过phash算法(内部调用HMAC算法(参数调用sha256,一种标准的hash加盐算法)),得到12字节的值,
这个值就是发给client的值,client验证不一致的话说明被篡改;

到这里握手完毕,到client向服务器发GET了。
注意GCM加密模式,这里开始读/写都算第二次加密了,因为读/写finished消息就是第一次加密。

  • END –
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

注:在使用本系统时,使用方必须在国家相关法律法规范围内并经过国家相关部门的授权许可,禁止用于一切非法行为。使用用途仅限于测试、实验、研究为目的,禁止用于一切商业运营,本团队不承担使用者在使用过程中的任何违法行为负责。

83源码 技术教程 代码角度看SSL握手过程 https://www.83ym.com/150.html

认准唯一TG:@ym830

常见问题
  • 站内所有资源,针对不同等级VIP会员可直接下载,特殊资源商品会注明是否免费,指会员所享有根据选择购买的会员选项所享有的特殊服务,具体以本站公布的服务内容为准。
查看详情
  • 按照我国的法律规定,运营网络棋牌首先需要成立一个注册正规备案的公司,然后申请网站备案、文网文、ICP等等,这些证件缺一不可。 一.注册公司 在当地工商进行注册,公司名称以“XX科技有限公司”为名,如:富裕棋牌经营范围填写“计算机软硬件、网络设备的设计开发与购销”。 二.域名及网站备案 在国内从事网站经营活动就必须经过相关部门的备案,因此棋牌运营商在购买了域名后,就要到当地网监局办理网站备案,或者请服务器提供商代为备案。 三.申请文网文 文网文全称为网络文化经营许可证,是从事经营性互联网文化活动所必需的资质。一般是需要到当地省一级(省、直辖市、自治区)的文化行政部门提出申请,并经由当地的文化行政部门合法批准。次资质要求申请公司注册资金必需达到1000万,并提供游戏版权证明文件。 四.申请ICP ICP又称为增值电信业务许可证,所有网络游戏运营商均需要办理ICP许可证,此证件要求公司注册资金1000万,需到当地市级通讯管理局办理。 五.申请文网游——游戏备案 根据《网络游戏管理暂行办法》(文化部第49号)的规定,国产网络游戏在上网运营之日起30日内应当按规定向国务院文化行政部门履行备案手续。 以上就是网络棋牌游戏正规运营所必需的资质证明。一般作为正规有实力的棋牌游戏开发公司,不光要具备所有的正规资质,而且会对投资者、代理商等合作伙伴给予相关指导和协助,与合作伙伴携手共赢!
查看详情

相关文章

猜你喜欢
官方客服团队

为您解决烦忧 - 24小时在线 专业服务