【技术文】SSL握手中的几个密码
- 一、Secret Keys
- 二、PreMaster secret
- 三、Master secret
- 四、如上握手的形象比喻
【技术文】SSL握手中的几个密码
今天和大家聊一聊SSL加密。前面其实更新过几篇关于SSL加密的文章,但因为涉及到加密算法、对称非对称、公私钥,所以确实很干,阅读量也并不好。我其实也在迟疑要不是更新这篇终章,因为阅读量不好,我心里其实并不好受,甚至会自我怀疑。
正文开始...
SSL的加密为了平衡安全和效率,做了很多工作,为了SSL的加密过程足够安全,SSL引入了很多密码:
- PreMaster secret
- Master secret
- session secret
随机密码为了足够随机会根据用户键盘结合cpu空闲算出一个随机数,作为初始化密码。而这些随机密码都是能让SSL足够安全。
接下来会比较枯燥,需要一些耐心。
一、Secret Keys
生成过程以及作用流程图:
pre secret key
二、PreMaster secret
PreMaster Secret
是在客户端使用RSA
或者Diffie-Hellman
等加密算法生成的。它将用来跟服务端和客户端在Hello
阶段产生的随机数结合在一起生成 Master Secret
。在客户端使用服务端的公钥对PreMaster Secret
进行加密之后传送给服务端,服务端将使用私钥进行解密得到PreMaster secret
。也就是说服务端和客户端都有一份相同的PreMaster secret
和随机数。premaster_secret
长度为 48 个字节,前 2 个字节是协议版本号,剩下的 46 个字节填充一个随机数。结构如下:
Struct {
byte Version[2];
byte random[46];
}
PreMaster secret
前两个字节是TLS
的版本号,这是一个比较重要的用来核对握手数据的版本号,因为在Client Hello
阶段,客户端会发送一份加密套件列表和当前支持的SSL/TLS
的版本号给服务端,而且是使用明文传送的,如果握手的数据包被破解之后,攻击者很有可能串改数据包,选择一个安全性较低的加密套件和版本给服务端,从而对数据进行破解。所以,服务端需要对密文中解密出来对的PreMaster
版本号跟之前Client Hello
阶段的版本号进行对比,如果版本号变低,则说明被串改,则立即停止发送任何消息。
三、Master secret
上面已经提到,由于服务端和客户端都有一份相同的PreMaster secret
和随机数,这个随机数将作为后面产生Master secret
的种子,结合PreMaster secret
,客户端和服务端将计算出同样的Master secret
。
Master secret
是有系列的hash
值组成的,它将作为数据加解密相关的secret的 Key Material
的一部分。Key Material
最终解析出来的数据如下:
mastersecretkeys
其中,write MAC key
,就是session secret
或者说是session key
。Client write MAC key
是客户端发数据的session secret
, Server write MAC secret
是服务端发送数据的session key
。MAC(Message Authentication Code)
,是一个数字签名,用来验证数据的完整性,可以检测到数据是否被串改。
keyprocess
四、如上握手的形象比喻
如果上面的说明不够清晰,这里我们用个形象的比喻,我们假设A与B通信,A是SSL客户端,B是SSL服务器端,加密后的消息放在方括号[]里,以突出明文消息的区别。双方的处理动作的说明用圆括号()括起。
A:
我想和你安全的通话,我这里的对称加密算法有DES,RC5,密钥交换算法有RSA和DH,摘要算法有MD5和SHA。
B:
我们用DES-RSA-SHA
这对组合好了。这是我的证书,里面有我的名字和公钥,你拿去验证一下我的身份(把证书发给A)。目前没有别的可说的了。
A:
(查看证书上B的名字是否无误,并通过手头早已有的CA
的证书验证了B的证书的真实性,如果其中一项有误,发出警告并断开连接,这一步保证了B的公钥的真实性) (产生一份秘密消息,这份秘密消息处理后将用作加密密钥,加密初始化向量(IV)和hmac的密钥。将这份秘密消息-协议中称为per_master_secret
-用B的公钥加密,封装成称作ClientKeyExchange
的消息。由于用了B的公钥,保证了第三方无法窃听) 我生成了一份秘密消息,并用你的公钥加密了,给你(把ClientKeyExchange
发给B) 注意,下面我就要用加密的办法给你发消息了!(将秘密消息进行处理,生成加密密钥,加密初始化向量和hmac的密钥) [我说完了]
B:
(用自己的私钥将ClientKeyExchange
中的秘密消息解密出来,然后将秘密消息进行处理,生成加密密钥,加密初始化向量和hmac的密钥,这时双方已经安全的协商出一套加密办法了) 注意,我也要开始用加密的办法给你发消息了![我说完了]
A:
[我的秘密是…]
B:
[其它人不会听到的…]
over...
- 《快学Scala》第一章 基础
- 移动端打印输出内容以及网络请求-vconsole.js
- 二分查找法的实现和应用汇总
- JavaScript前端和Java后端的AES加密和解密
- 《Spark MLlib 机器学习实战》1——读后总结
- angularjs自定义指令实现分页插件
- A+B for Input-Output Practice (V)
- 机器学习——相似度算法汇总
- 白话推荐系统——从原理到实践,还有福利赠送!
- 基于Spring Boot的Logback日志轮转配置
- Java程序员的日常—— Spring Boot单元测试
- Windows下TensorFlow安装指南(图文版)
- 20120918-双向链表类定义《数据结构与算法分析》
- 20120918-LIST类定义《数据结构与算法分析》
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- app反编译遇到360加固,傻瓜式脱壳
- Java底层-本地接口(JNI)
- 如何从最坏、平均、最好的情况分析复杂度?
- 利用Python进行MR栅格数据处理
- 利用Sql处理MR栅格数据
- Netty组件之Channel注册
- 使用 kubeadm 安装单 master kubernetes 集群
- 垃圾回收算法(4)-复制算法
- Digital-Signature-Hijack:一款针对数字签名劫持的PowerShell脚本
- 使用TensorFlow物体检测模型、Python和OpenCV的社交距离检测器
- 基于OpenCV和Tensorflow的深蹲检测器
- BBPress未经身份验证的提权漏洞分析
- 开源日志管理系统Graylog之Sidecar功能实践
- CentOS-AltArch-7(ARM版)下源码编译MySQL5.7.31
- 用BurpSuit的Burpy插件搞定WEB端中的JS加密算法