在RSA公私钥体系中,存在满足以下关系的三个自然数e, d, n:
其中,n是两个大质数p, q的乘积,当n为2048-bit时,p, q均在1024-bit左右。
输入数字a的加密过程
将b还原为a的解密过程
由于篇幅所限,我在这里略去对RSA加解密的数学背景知识的介绍。对这部分知识有疑问的同学请参考[这个页面](http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html
)。
(e, n)作为公钥发放给使用者,(d, n)则作为私钥保留在服务器端。在HTTPS通信过程中,服务器只会传递公钥,而私钥永远不会被传输,并且,使用公钥加密的信息只能用私钥才能解开,而能被公钥解密的信息则一定是被私钥加密过的。
在HTTPS协议中,一般仅使用RSA这种非对称加密算法来传输用于加密实际页面数据的对称加密算法的一个伪随机数k。目前比较主流和安全的对称加密算法是AES-128。采用AES-128时,k是一个128-bit的随机数,k被通过RSA加密传输后,实际页面数据的加解密就以k为密钥用AES-128进行。这主要是由于RSA无法加密长度超过n的字节长度的数据,实际应用中,n一般不超过4096 bits,即512字节,而普通页面的数据长度远大于这个值。
当浏览器和一个HTTPS服务器建立连接后,服务器会向浏览器发送一个包含RSA公钥, 签名,签发机构,持有者信息,域名模式和有效期等信息的证书。浏览器从以下几个方面校验该证书的有效性:
- 是否在有效期内
- 携带的域名模式是否匹配访问的域名
- 是否由一个合格的签发机构签发
- 证书签名是否正确
前面两点,有效期和域名模式的校验是容易理解的。我着重说明后面两点,签发机构和签名的校验。
HTTPS证书存在一个层级结构,一般情况下分为三层,第一层是签发机构自签名的根证书,第二层是签发机构用自己的根证书签名的一个分级证书,例如class 1表示个人用户,class 2表示企业用户,或者,class A表示网站服务,class B表示email服务,第三层才是使用分级证书签名提供给网站用的证书。
“签名”其实就是用上一级证书里的RSA公钥对应的私钥来对下一级证书内容的散列值进行加密,并将加密后得到的数字以及所用的散列算法类型写入下一级证书中。证书内容的散列算法经历了MD5->SHA1->SHA2的变迁,目前仅有SHA2被认为是安全的。
校验签名的步骤如下:
- 对证书除签名以外的部分按证书的散列算法类型计算出散列值,将这个值记作H1
- 对证书签名S用上级证书中的公钥进行解密,将这个值记作H2
- 如果H1和H2相等,签名校验通过,否则不通过
三层HTTPS证书,分别为根证书,分级证书和网站证书。其中,根证书已内置于浏览器,因此web server只需传输分级证书和网站证书。浏览器先使用内置的根证书来校验分级证书的有效性,如果分级证书校验通过,再使用分级证书来校验网站证书的有效性。网站证书也校验通过后,假设有效期和域名模式都没问题,浏览器用网站证书的公钥将一个随机生成的对称密钥加密后发送给服务器,让服务器使用这个新生成的对称密钥来加密要传输的页面内容。如果任何一层证书未通过校验,浏览器就会弹出一个安全警告提醒用户注意并让用户确认是否继续访问该页面。