计算机网络 - HTTPS
HTTP & HTTPS
有一个前提就是:在网络信道传输的数据是任何人都可以截获的。由于这个特性,再加上HTTP的明文传输,就有非常大的不安全隐患。如何保证安全?那是不是我把传输的明文数据加密, 在信道里是一堆看不懂的字节,然后让接收方解密就可以了呢?这仍然会存在一些问题,如:
- 如何保证加解密的秘密性,如果黑客知道了你怎么加密,怎么解密的,那这个加解密就没有意义了
- 如何验证身份,如果黑客把数据加密发给服务器,或是发给客户端,他们要怎么知道对方不是他们想要的人
- 如何保证信息的完整性,即时黑客不知道怎么加解密,他通过一些加密后的数据的排列重组,制造虚假信息,或者以此来试探解密方,怎么解决。
这里就涉及到安全的定义,什么是网络通信安全?
安全的四个特性
- 机密性 Secrecy
即只有可信方才能看见数据,其他任何人都“看不见”数据(或者说不知道数据的含义)。 - 完整性 Integrity
数据在传输过程中,没有被窜改,原封不动地传给接收方。 - 身份认证 Authentication
也就是机密性里说的“可信方”。如何判断“可信方”,如何保证接收人,或者发送者是“可信”的。 - 不可否认 Undeniable
保证通信事务真实性,即存在过的通信,是不能抵赖的。
HTTPS 与 HTTP
我们知道,HTTPS是安全的,而HTTP是不安全的。那他们两者有什么区别呢?其实区别非常小,HTTPS只比HTTP多了一层SSL/TLS的协议而已,如下图:
那么重头戏来了,什么是SSL/TLS,他们又是如何保证安全的呢?
SSL/TLS
定义
SSL即Secure Sockets Layer,安全套接层,TLS即Transport Layer Security, 传输安全层。我们可以把他们理解成一个东西,TLS1.0就是SSL3.1, 由于SSL已经是声名大噪了,所以即便改名为TLS了,人们还是喜欢把他们放在一起说,即SSL/TLS。目前应用最广泛的就是TLS1.2
加解密
首先我们需要对加解密有一个“数学上的感性认知”。对于加密,咱们就是要把“一句有意义的话”变成一堆“乱码”,这个乱码要到什么程度,最好就是到,只有可信方能“很快”还原乱码,其他人都还原不了或者要费很大力气才能还原的程度,这也就是解密。在数学上,这个方法叫做单向陷门函数。
- 单向函数
对于已知f,容易计算y=f(x);而对于已知y,假设存在y=f(x),很难由此推断/计算得到x,那么f就是单向函数 - 单向陷门函数
已知f,陷门h,容易计算y=f(x,h);而对于已知y,假设存在y=f(x,h),很难由此推断/计算得到x,但如果已知y,h,又能很快推到出x, 那么f就是单向陷门函数
根据上述定义,我们不难感觉到,f单向陷门函数就是我们的加解密算法,h就是我们的秘钥。在非对称加密中,f的参数可以算是我们的公钥,而陷门h就是我们的私钥。这里说到公钥私钥,也就得先说说对称加密和非对称加密了。
对称加密 & 非对称加密
- 对称加密
即加密方和解密方共用同一个秘钥,机密性依赖于秘钥的机密性。常见的算法是AES。
🌵问题:如何保证秘钥的机密性? - 非对称加密
即加密方用公钥加密,解密方用私钥解密,公钥可公开,私钥需要保密。常见的算法是RSA(基于“整数分解”数学难题), ECC(基于“椭圆曲线离散对数”数学难题),ECC比RSA高效的地方在于,RSA达到安全需要2048位的秘钥,而ECC相同程度只需要224位。
🌵问题:如何保证此公钥即为服务器颁布的公钥而不是黑客伪造的公钥?公钥是公开的,如何保证黑客不会拿到公钥伪造你的信息发给服务器呢?
加解密算法基于数学难题,其实就是我们上述说的单向陷门函数中的“很难推导”出x。这么多数学家这么多年都无法解决的问题,拿来做加解密真的感觉非常有意思。其实也就是说,如果上述难题哪天被解决了,那这个加解密算法也就不安全了。
非对称加密比对称加密的代价更高,此处的代价指计算代价。由于网络通信追求安全的同时也追求效率,所以通信过程中一般是采取对称加密。那么对称加密的秘钥也需要通信双方约定好,也需要在网络信道里传输,那么也存在安全问题(开始了,鸡生蛋,蛋生鸡)。所以对秘钥的传输,使用的就是非对称加密的方式。这即是SSL/TLS使用的混合加密的方式。
HTTPS(SSL/TLS)使用非对称和对称混合的加密方式
首先,由于非对称加密的时间和处理成本都高于对称加密,所以在网络访问这个场景,还是应该使用对称加密,而对称加密的秘钥就很重要,它只能被浏览器和服务器两者知晓,不应该被三方窃取。
所以,想到了先使用非对称加密将秘钥进行双方通个气,私钥放在服务器比较安全,那浏览器怎么知道不同网站的公钥是多少呢,操作系统也不能内置这么多网站的公钥,所以有了一个第三方CA机构。所有网站需要像第三方CA机构申请数字证书,这个申请需要给出自己的公钥,还有网址等,CA之后就开始制作该证书,并用私钥加密后返回给服务器。
客户端操作系统只需要内置全球的CA机构的公钥就行,当请求服务器的时候,服务器先把自己的证书发过来,浏览器依据各个CA的公钥进行解密,只要有一个可以解出正确的证书,那就也拿到了该网站的公钥,且可以和请求的网址做对比,防止黑客去申请了证书,中途进行了拦截。至此,浏览器和服务器可以通过非对称加解密交换AES秘钥,之后的请求就使用对称加解密进行了。
这就是SSL/TLS的原理。
数字证书
上面非对称算法里提到的一个遗留问题,“公钥信任问题”。这个时候,我们采用第三方担保机构,CA(Certificate Authority)来保证这个公钥就是服务器的公钥。而这个公钥,颁布者,有效时间等等打个包再签名就形成了“数字证书”。操作系统和浏览器中内置了各大CA的根证书,服务器发过来证书可以验证公钥的可信性。
数字签名
上面还提到了一个问题就是,“身份认证问题”。也就是如何证明“你是你”呢?
现实生活中,我们通过签名,按手印,盖章来保证身份问题。他们的共同点就是都使用了一些只有你才有的特征/东西,如笔迹,指纹等。TLS中,这种特征就是“私钥”,所以网页会把返回内容的摘要(Digest, 下面会讲),用私钥加密,生成数字签名,一同返回给客户端,客户端收到后,用公钥解密,再比对摘要是否一致,来判断这是“你”发的,而不是某个黑客发过来的。
数据完整性保证
安全定义中提到的完整性,如何保证呢?这里就需要用到“摘要算法”,也就是散列函数/哈希函数。这个摘要算法其实只需要一个“单向函数”,不需要解密,我们在传输数据的时候,把摘要算法算出的结果也附在下面,再一同加密,那么收信方解密后,再算一遍这个单向函数来比较一下,一致就说明没有被更改,不一致就说明数据被窜改了。
我们日常用的最多的摘要算法就是MD5, SHA-1。他们也用作比较文件是否一致等等其他用途了。
TLS的连接过程
RSA的握手过程
我们知道建立TCP连接需要三次握手,而HTTPS因为建立在TLS的协议上,握手过程还比必须要遵守TLS层的规定,其过程如下:参考链接
第一张图其实是TCP的三次握手,其主要目的是服务器把他的公钥(数字证书,可以看上面的内容)和他使用的密码套件发送给客户端。
第二张图才是TLS的三次握手,其主要目的是服务器和客户端商量好公钥。客户端将服务器的公钥加上自己和服务器的随机数搞一个专属公钥出来,然后通过Change Cipher Spec发给服务器,这部分就是非对称加密的应用啦。
第三张图,就是约定好后的通过对称加密,使用专属公钥进行正常网络通信的样子~
密码套件 Cipher Suite
如下图,密码套件的基本形式是:密钥交换算法 + 签名算法 + 对称加密算法 + 摘要算法。 ECDHE-RSA-AES256-GCM-SHA384的意思就是,咱们交换密钥用ECDHE进行,用RSA签名和身份验证,握手后用AES对称加密进行通信,其密钥长度为256位,分组模式是GCM,摘要算法为SHA384用于消息认证和产生随机数。