访问https的网站被告知证书不安全, 这个证书是啥?
对称加密
密钥只有一个, 加密和解密都是用这个
非对称加密
加密用公钥, 解密用私钥, 公钥大家都能看到, 私钥就藏在服务器里
对于https里的非对称加密, 公钥和私钥都可以进行加密和解密
证书
证书包括持有人的身份信息, 公钥, 以及数字签名, 可以参考自签名证书
简单的说,就是为了防止中间有窃听者冒充服务器, 客户端通过权威机构颁发的证书来验证服务器的证书是否合法, 达到确认服务器就是真的服务器, 而不是伪造的
数字签名
就是用持有者的私钥把证书内容择要进行加密, 用持有者公钥可以解. 一般这个持有者是全球权威的几个CA, 会把公钥内嵌到各个浏览器厂商
自签名证书
自己充当ca角色.
扮演ca角色, 首先需要生成ca.crt文件(包括ca的公钥, 数字签名)
然后通过ca.crt 及ca.key, 给服务器签发带有ca签名的证书 server.crt(包括server的公钥, 及签名(用ca.key签名过的hash), 这个签名用ca的公钥可以解)
客户端在建立连接前, 会得到server.crt, 然后用ca.crt来验证他(自签名证书的ca.crt需要安装到客户端,如果是全球权威机构的ca, ca.crt已经预装了).
https 加密方式
https 是先通过非对称加密的方式获取到会话密钥, 然后客户端和服务端用会话密钥进行对称加密
具体过程是
客户端: 发起请求
服务端: 返回ssl证书X, 里面包含ca机构名称, 公钥, 签名
客户端: 验证证书是否合法, 如果合法, 将一个随机数B用公钥加密
如果是自签名的网站, 浏览器在系统里就找不到这个ca, 就好在页面警告, 这个时候下载安装这个ca证书就行
如果在系统里找到了这个证书, 用证书里的公钥解密服务端发来的证书X里的签名, 是否和X的hash择要一样, 如果一样, 说明这个公钥可以使用. 做这一步是为了防止服务器证书被篡改
服务端: 用私钥解密出B, 成功后, 把B当做session secret(会话钥), 后续通过会话钥进行对称加密
http => https的演化过程
对称加密
双方都用一个密钥进行加密和解密, 这个密钥很容易被盗取, 导致加密失败
非对称加密
如果中间有一个黑客, 即扮演服务器, 又扮演客户端, 那这个黑客是可以盗取交流的信息
所以需要确定一个服务器是否是正真的服务器, 而不是黑客
对称加密和非对称加密结合,并且使用证书
在建立连接之前, 需要验证证书, 只有证书通过了后, 才能建立对称加密会话, 进行通信
图表源码
@startuml
title https握手过程
actor P1
P1 -> server : 请求服务端证书server.crt
note right : 包括签名S1, 服务器公钥P等
server -> P1 : server.crt
P1->P1 : 验证证书
note left
客户端的CA的公钥来解密S1 得到 证书摘要 hash_1
如果S1篡改过, 用CA的公钥是解不开的
通过特定的摘要算法得到证书摘要 hash_2
对比是否一致
end note
P1 -> server : 用P加密一个随机数
server -> P1 : 用私钥解密这个随机数, 用作会话密钥, 开始对称加密
@enduml
引用
- 深入浅出nodejs
- https扫盲
- 会话密钥的产生
- http向https演化的过程