HTTPS 笔记
HTTPS 笔记
HTTPS 也可以叫做 HTTP over TLS 或者 HTTP over SSL。
数据在互联网中传输时,中间要经过需要中间节点,而中间节点的安全性并不能被保证,可能会被监听或者修改,而 HTTPS 主要可以防止中间人攻击。
证书
key 文件,私钥
csr(Certificate Signing Request),证书签名请求,这不是证书,可以简单理解成公钥,生成证书时要把这个提交给 CA。
crt (certificate),证书。.crt
证书文件,常见于*NIX
系统,大多数是 pem 编码。
cer(certificate),也是证书。常见于 Windows 系统,大多数应该是 der 编码。
X.509
是一种证书格式。对X.509
证书来说,认证者总是CA或由CA指定的人,一份X.509
规定了证书需要包含哪些信息,这些字段包含有关用户及其相应公钥的信息。
X.509
的证书文件,一般以.crt
结尾,根据该文件的内容编码格式,分为 pem 和 der 二种格式,这两种格式可以互相转换。
pem,Privacy Enhanced Mail。以文本格式存储,以-----BEGIN...
开头, -----END...
结尾,内容使用 BASE64 编码。(Apache
和*NIX
服务器偏向于使用这种编码格式)
der,Distinguished Encoding Rules,以二进制格式存储,不可读。(Java 和 Windows 服务器偏向于使用这种编码格式)
jks(Java Key Storage)这是 Java 的专利。跟 OpenSSL 关系不大,利用 Java 的一个叫keytool
的工具,可以生成.jks
文件,也可以将.pfx
转为jks
。
自签名证书:
使用 openssl 来进行 SSL 的操作。(当年大名鼎鼎的「心脏出血」漏洞发生的库哈哈)
生成使用 RSA 算法的私钥server.key
openssl genrsa -des3 -out server.key 2048
使用私钥 server.key
,生成证书请求文件server.csr
。这里会进入交互模式,需要填一堆信息,比如组织地址名称邮箱,注意Common Name
填域名。
openssl req -new -key server.key -out server.csr
使用私钥 server.key
,生成X.509
格式证书ca.crt
作为 CA 证书
openssl req -new -x509 -days 3650 -key server.key -out ca.crt
用CA的证书ca.crt
给自己的证书请求文件server.csr
签名和加密。生成自签名证书 server.crt
openssl x509 -req -days 3650 -in server.csr \
-CA ca.crt \
-CAkey server.key \
-CAcreateserial -out server.crt
获取一个正常证书:
- 自己生成一对私钥和证书签名请求文件
.csr
。 - 把
.csr
文件上传到 CA 认证机构,填写信息。之后 CA 认证机构使用开发者指定的哈希算法,对证书部分内容进行签名(网站域名,网站公钥,此证书哈希算法,比如 MD5 或者 SHA256),然后使用 CA 机构自己的私钥对证书进行加密(有时候把这个签名和加密的过程说成「签名」)。 - CA 机构把「签名」过的证书,再发送给申请者手中(一般就是通过邮件)。
- 拿到这个 CA 机构「签名」过的证书,就可以正常部署在自己 web 服务器上使用了。
客户端的验证服务端证书的方法:
客户端收到的网站证书主要内容包括:网站域名,网站公钥,此证书哈希算法,比如 MD5 或者 SHA256。这些内容是使用指定的哈希算法签名,然后再经过了 CA 使用自己的私钥使用比如 RSA 算法加密过的。
客户端得到服务器发来的加密证书后,使用各家 CA 储存在客户端本地的公钥对 证书 进行解密,得到这个网站证书的哈希签名。
证书里有一个签名和加密算法字段,比如 sha256RSA 表示,CA机构是使用 SHA256 对证书进行签名,然后使用CA机构的私钥,通过 RSA 算法对签名进行加密的。
使用证书指定的签名算法对证书内容签名,也得到一个签名。
对比两个签名是否一致,如果一致则检查通过。
单向验证流程:
- ClientHello。协商本次对话使用的各项参数(客户端发送支持的 SSL / TSL 指定版本,加密组件 Cipher Suite 列表,也就是加密算法和密钥长度)。一个随机数
radom1
,稍后用于生成对话密钥session Key
- ServerHello。服务端从这些选项中选出本次使用的参数。服务端的证书。另外也发送一个随机数
radom2
,稍后用于生成对话密钥session Key
- Certificate。客户端验证服务端出示的证书,或使用其他方式进行身份验证;
- ServerKeyExchange。对将用于保护会话的对称主密钥
session Key
达成一致。验证通过之后,客户端会生成一个随机数pre-master secret
,然后使用证书中的公钥进行加密,然后传递给服务器端,服务端将使用私钥进行解密得到PreMaster secret
。此时,服务端根据 radom1、radom2、pre-master secret 通过一定的算法得出 session Key 和MAC 算法秘钥,作为后面交互过程中使用对称秘钥。同时客户端也会使用 radom1、radom2、pre-master secret,和同样的算法生成 session Key 和 MAC 算法的秘钥。
PreMaster secret
前两个字节是TLS的版本号,这是一个比较重要的用来核对握手数据的版本号,因为在 Client Hello 阶段,客户端会发送一份加密套件列表和当前支持的SSL/TLS
的版本号给服务端,而且是使用明文传送的,如果握手的数据包被破解之后,攻击者很有可能篡改数据包,选择一个安全性较低的加密套件和版本给服务端,从而对数据进行破解。所以,服务端需要对密文中解密出来对的PreMaster
版本号跟之前 Client Hello 阶段的版本号进行对比,如果版本号变低,则说明被篡改,则立即停止发送任何消息。
生成 session Key 的过程中会用到PRF(Pseudorandom Function伪随机方法)来生成一个key_block
,然后再使用key_block
,生成后面使用的秘钥。
进行内容的传输时,客户端先使用 MAC秘钥
对内容进行摘要,然后把摘要放在内容的后面使用 sessionKey
再进行加密。
服务器端收到之后,先使用 client_write_key
进行解密,然后使用 client_write_MAC_key
对数据完整性进行验证。
服务器端发送的数据,客户端会使用 server_write_key
和 server_write_MAC_key
进行相同的操作。