Https通信基本过程
在通信过程中,https是如何保证数据安全?如何保证是对的服务器?如何保证数据完整性?
以下是客户端发起https请求的时候的流程:
- 客户端发送随机数client_random和支持的加密方式列表
- 服务器返回随机数server_random,选择的加密方式和证书(经过ca颁发,或者自签名的证书,该证书包含公钥)
- 客户端验证服务端证书,使用证书中的公钥加密premaster secret发送给服务端
- 服务端使用私钥解密得到premaster secret
- 两端分别通过client_random,server_random和premaster secret生成master secret,用于对称加密后续通信内容
整个过程主要的作用是让双方安全地协商出一个key,这个key会用于对称加密中。第三方即使截取了所有的通信数据,也是无法获取到这个key的。既然第三方无法获取这个key,自然也对加密过的数据无可奈何了。
tcp 连接层做的事儿是发送请求,至于发送几次请求认为是连接建立好了,是应用层决定的事儿。
如上步骤,HTTPS 连接是基于tcp 4次握手,大家都知道http 建立连接是基于tcp三次握手,
所谓的HTTPS的加密传输 只是通过TCP层的四次握手协商出来了一个对称秘钥而已。
HTTPS 的协商过程是明文的,因为证书,所以中间人就算拿到明文也没有用。
什么是RSA非对称加密
在解答上面的问题之前,首先我们得先了解一些基本的知识:
RSA非对称加密:RSA分为公钥和私钥,从私钥可以生成公钥,但是不能通过公钥生成私钥。公钥加密过的信息,只有私钥能解开,私钥加密的信息,只有公钥能解开
https如何保证key不会被中间人窃取
在步骤(1)中,客户端的随机数client_random是完全可以被中间人窃取的,然后在步骤(2)中服务端返回的server_random也是完全可被中间人窃取的。关键是在步骤(3),客户端会把生成的premaster secret通过公钥进行加密,然后再发送给服务器,中间人当然也可以窃取加密后的premaster secret数据,但是中间人却不能解密出原始的premaster secret,这是为什么呢?因为公钥加密的数据,只有私钥能解开,而私钥是保存在服务端,不会外泄的!通过步骤1-4,服务器和客户端相互持有了client_random,server_random和premaster secret,而且只有客户端和服务端才有premaster secret,中间人是没有的。这时候通过前面三个key,生成master secret用于对称加密,确保通信安全。
为何最终使用对称加密,而不是全部通信都使用非对称加密呢?猜测是因为非对称加密效率和速度不如对称加密。而且对称加密的安全性并不是不高,对称加密的难点在于如何安全地交换key。
如何确认对方就是“正确的人”,而不是其他中间人呢
我一开始理解https的时候,遇到一个困惑:如果中间人从建立连接一开始就冒充服务器,转发客户端和服务端的所有数据,那么所有数据在中间人眼里应该都是透明的啊,中间人应该也能解密通信数据啊?其实不是的,如果不是正确的服务器,在第四步的时候的时候,假服务器是无法解析出正确的premaster secret,所以就不会有正确的master secret ,这个解析premaster secret 的过程依靠的是只有服务器自己才知道的私钥。
那么,什么是证书(CA颁发的“身份证”)呢?
什么是证书呢?
数字证书的发证机关是证书管理机构(certificate authority,CA),在这里CA是一个权威的机构,我们可以信任他,他信任的站点,我们也会认为是可信任的。就是所有网站都要去CA机构那里去登记,然后CA会发给那么网站一个“身份证”。
证书生成的步骤?
证书格式是什么样的?
-
服务端生成自己的证书请求文件(尚未被CA添加数字签名),里面包含了姓名、公钥等信息
-
CA机构对该证书进行签名,也就是生成数字签名,注意,这个签名是用CA的私钥加密过的
-
把原始的证书和生成的数字签名合并在一起,形成证书
如何验证证书真伪?
在https的步骤(2)的时候,服务器发给用户的证书就是这个签名过之后的证书,客户端收到证书后,会使用CA的公钥对数字签名进行解密得出一个信息摘要,然后用哈希算法自己算出信息摘要,对比摘要,一致的话,证明该证书是CA机构颁发的。因为公钥只能解开私钥加密的数据,如果信息摘要是匹配的,那么证明该加密数据是由CA机构用私钥加密的,证书是可靠的。
万一冒牌网站把正牌网站copy下来,转发给我了怎么办,转发的证书是由正牌网站copy的,肯定是真的,所以客户端可以验证通过的,那怎么办?
确实是的,如果冒牌网站用正版网站的证书来忽悠客户端,那么客户端确实是会被“忽悠”过去的,但是不用担心,客户端是依靠证书上的公钥来生成premaster secret的,而公钥对应的私钥,冒牌网站是不可能拿得到的,也就不可能解密出正确的premaster secret,自然也无法正常和客户端正常沟通了。
万一冒牌网站把正牌网站copy下来,并且拦截了客户端的请求,客户端该怎么辨别真假呢?
这就需要客户端在访问服务器的时候把服务器的证书添加到信任列表里,然后加个校验,如果服务器证书不在列表里,则认为服务器有问题,连接失败。
在通信过程中,https是如何保证数据安全?如何保证是对的服务器?如何保证数据完整性?
通过加密保证数据安全
通过验证服务端证书的正确性和premaster secret 的协商来保证是正确的服务器。
通过对加密后的数据 进行 hash运算来保证数据完整性
https 证书相关的几个概念:
1 Keytool 是一个有效的安全钥匙和证书的管理工具,Java 中的 keytool.exe (位于 JDK\Bin 目录下)可以用来创建数字证书
2 证书库,是用来存储证书用的,常用的有.jks/.ks .p12/.pfx .jce .bks .ubr 这五大类
3 证书库里当然会存储证书了,证书库里的证书可以导出。
4 证书库为了保证库的安全,再生成证书库的时候,可以设置一个密码,这就是 证书库密码。
5 如果想要服务器端信任客户端,需要把客户端证书导入服务器端的证书库,如果想要客户端信任服务器端,也需要把服务器端的证书导入到客户端的证书库里。
6 证书库里包含 私钥,公钥和对应的数字证书的其他信息,但是证书库导出后的证书文件里只包括主体信息和对应的公钥以及数字签名
7 私钥 :是一个实体自定义的一个字符串,只有他们自己知道。用这个私钥 可以加密实体信息,生成 实体对应的数字签名。
而这个签名只有 公钥才可以解开。
8 公钥:公共钥匙用来检验签名;如果服务器的证书是假的,那他给出的签名就是假的,通过判断服务器给出的签名就知道服务器是否是欺骗着。
9 签名: 用私有钥匙加密某些消息,从而得到加密数据; 用来表示服务器的唯一性。
常见的证书格式
证书是存储了公钥,私钥,数字签名,加密算法, 以及其他相关信息的凭证。
因为证书内部存的内容比较多,所以就必须固定格式,这样才方便解析里面的内容。
现有的ca机构颁发的证书也不是统一的一套格式,目前有2套 格式标准,
一类是 依据X.509(1993)格式 二类是 依据PKCS系列的格式。
密钥库文件格式【Keystore】 (秘钥库都是包含私钥的)
格式 : JKS
扩展名 : .jks/.ks
描述 : 【Java Keystore】密钥库的Java实现版本,provider为SUN
特点 : 密钥库和私钥用不同的密码进行保护
格式 : JCEKS
扩展名 : .jce
描述 : 【JCE Keystore】密钥库的JCE实现版本,provider为SUN JCE
特点 : 相对于JKS安全级别更高,保护Keystore私钥时采用TripleDES
格式 : PKCS12
扩展名 : .p12/.pfx
描述 : 【PKCS #12】个人信息交换语法标准
特点 : 1、包含私钥、公钥及其证书
2、密钥库和私钥用相同密码进行保护
格式 : BKS
扩展名 : .bks
描述 : Bouncycastle Keystore】密钥库的BC实现版本,provider为BC
特点 : 基于JCE实现
格式 : UBER
扩展名 : .ubr
描述 : 【Bouncycastle UBER Keystore】密钥库的BC更安全实现版本,provider为BC
证书文件格式【Certificate】
格式 : X509 DER
扩展名 : .cer /.crt
描述 : 【ASN .1 DER】用于存放证书
特点 : 不含私钥
.crt 这样的证书文件可以是二进制格式,也可以是文本格式,一般均为文本格式
*.DER或*.CER文件: 这样的证书文件是二进制格式,只含有证书信息,不包含私钥
格式 : X509 PEM
扩展名 : .pem
描述 : 【Printable Encoded Message】
特点 : 1、该编码格式在RFC1421中定义,其实PEM是【Privacy-Enhanced Mail】的简写,但他也同样广泛运用于密钥管理
2、ASCII文件
3、一般基于base 64编码
4. Apache 用到的CA证书链就是PEM格式,它实际上可保存普通多个X509证书(.cer), 将每个证书简单加在一起就可以了
*.PEM文件: 这样的证书文件一般是文本格式,可以存放证书或私钥,或者两者都包含。 *.PEM 文件如果只包含私钥,一般用*.KEY文件代替
格式 : PKCS7
扩展名 : .p7b/.p7r
描述 : 【PKCS #7】加密信息语法标准
特点 : 1、p7b以树状展示证书链,同时也支持单个证书,不含私钥
2、p7r为CA对证书请求签名的回复,只能用于导入
格式 : CMS
扩展名 : .p7c/.p7m/.p7s
描述 : 【Cryptographic Message Syntax】
特点 : 1、p7c只保存证书
2、p7m:signature with enveloped data
3、p7s:时间戳签名文件
格式 : PKCS10
扩展名 : .p10/.csr
描述 : 【PKCS #10】公钥加密标准【Certificate Signing Request】
特点 : 1、证书签名请求文件
2、ASCII文件
3、CA签名后以p7r文件回复
格式 : SPC
扩展名 : .pvk/.spc
描述 : 【Software Publishing Certificate】
特点 : 微软公司特有的双证书文件格式,经常用于代码签名,其中
1、pvk用于保存私钥
2、spc用于保存公钥