文章目录
概念
HTTPS(HyperText Transfer Protocol over Secure Socket Layer)并不是一个新鲜的协议,可以理解为HTTP + SSL/TLS,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因为加密传输数据需要SSL,用于安全的HTTP数据传输。
默认端口号为443。
SSL(Secure Socket Layer,安全套接字层):SSL 协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。
TLS(Transport Layer Security,传输层安全):其前身是SSL。
HTTP访问过程
通过抓包,可以发现:
HTTP请求过程中,客户端与服务器之间没有任何身份确认的过程,数据全部明文传输,“裸奔”在互联网上,所以很容易遭到黑客的攻击,如下:
可以看到,客户端发出的请求很容易被黑客截获,如果此时黑客冒充服务器,则其可返回任意信息给客户端,而不被客户端察觉,所以我们经常会听到一词“劫持”。
所以HTTP传输面临的风险有:
- 窃听风险:黑客可以获知通信内容;
- 篡改风险:黑客可以修改通信内容;
- 冒充风险:黑客可以冒充他人身份参与通信。
HTTP 向 HTTPS 演化的过程
对传输的信息进行对称加密
如上图所示,此种方式属于对称加密,双方拥有相同的密钥,用同一个密码加解密,只要这个密钥不公开给第三者,同时密钥S足够安全,信息就可以得到安全传输,而且服务器与每个客户端的对称加密密钥必须不同,否则相当于没加密(相当于密钥公开),因此服务器与每个客户端使用不同的对称加密算法或不同的密钥,但此种方式的缺点是:
- 不同的客户端、服务器数量庞大,所以双方都需要维护大量的密钥,维护成本很高;
- 因每个客户端、服务器的安全级别不同,密钥极易泄露。
因此加密密钥不能较死板的存储在服务器或客户端上,不现实(每个客户端都要存一个密钥),也不安全。
那怎么办呢?既要使用不同的加密算法或者不同的密钥,有不能定死。
通过协商来决定。
但是,协商的过程是没有加密的,还是会被中间人拦截。那么再对这个协商过程进行对称加密就好了,那对协商过程加密的加密还是没有加密,怎么办?再加密不就好了…
对协商过程进行非对称加密
非对称加密特点是公钥加密只能用私钥解密,而私钥加密所有公钥都可以解密,客户端持有公钥,服务器持有私钥。
虽然服务器端向A、B…的方向还是不安全的,但是至少A、B向服务器端方向是安全的。
怎样协商可以确定不同加密算法或密钥
要达到服务器针对每个客户端使用不同的对称加密算法或密钥,同时,又不能让第三者知道这个对称加密算法或密钥是什么,怎么办?
使用随机数,就是使用随机数来生成对称加密算法或密钥。这样就可以做到服务器和客户端每次交互都是新的加密算法或密钥、只有在交互的那一该才确定加密算法或密钥。
客户端怎么获取非对称加密公钥
如果使用非对称加密算法,客户端A,B需要一开始就要持有公钥,要不没法开展加密行为。
如何让A、B客户端安全地得到公钥?
- 服务器端将公钥发送给每一个客户端;
- 服务器端将公钥放到一个远程服务器,客户端可以去远程服务器请求得到。
我们选择方案1,方案2又多了一次请求,还要另外处理公钥的放置问题。
但是服务器将公钥发给客户端时,可能被中间人掉包。
但是让每个客户端默认保存所有网站的公钥又不现实。
数字证书解决公钥被掉包问题
公钥被调包的问题出现,是因为客户端无法分辨返回公钥的人到底是中间人,还是真的服务器。这其实就是密码学中提的身份验证问题。
首先,不能对公钥传递过程加密,因为现在就是在处理加密安全性问题,显然不能绕进去。
因此如果选择直接将公钥传递给客户端的方案,始终无法解决公钥传递被中间人调包的问题。
所以,我们不能直接将服务器的公钥传递给客户端,而是第三方机构使用它的私钥对我们的公钥进行加密后,再传给客户端。客户端再使用第三方机构的公钥进行解密。
数字证书
证书中只有服务器交给第三方机构的公钥,而且这个公钥被第三方机构的私钥加密。
如果能解密,就说明这个公钥没有被中间人调包。因为如果中间人使用自己的私钥加密后的东西传给客户端,客户端是无法使用第三方的公钥进行解密的。
数字签名
在以上数字证书情况下,依然存在公钥被掉包问题。
因为存在这样一种场景:
第三方机构不可能只给你一家公司制作证书,它也可能会给中间人这样有坏心思的公司发放证书。这样的,中间人就有机会对你的证书进行调包,客户端在这种情况下是无法分辨出是接收的是你的证书,还是中间人的。因为不论中间人,还是你的证书,都能使用第三方机构的公钥进行解密。
第三方机构向多家公司颁发证书的情况:
客户端能解密同一家第三机构颁发的所有证书:
最终导致其它持有同一家第三方机构证书的中间人可以进行掉包:
因此客户端需要验证证书没有被掉包。
注意:这里的“掉包”,并不是指将整个证书完整的掉包。因为证书上有主题(Subject),这个主题表明这个证书是发布给谁的,或者说证书的所有者,一般是某个人或者某个公司名称、机构的名称、公司网站的网址等。因此掉包时中间人显然要将自己证书的主题改写。
因此证书掉包问题就变成了证书篡改问题。即验证证书没有被篡改。
那么问题就来了,这个验证工作放在哪?
- 放在第三方机构(远端服务);
- 放在本地客户端;
方案2比较合适,如果放在第三方机构,又得考虑信息安全问题,而且在第三方机构,远程服务,整个交互会变慢。
证书验证放在本地。
怎么验证证书没有被篡改? 数字签名
证书上写着如何根据证书的内容生成证书编号。客户端拿到证书后根据证书上的方法自己生成一个证书编号,如果生成的证书编号与证书上的证书编号相同,那么说明这个证书没有被篡改的。
同时,为避免证书编号本身又被篡改,所以使用第三方的私钥进行加密。
上图列出了数字证书主要的信息。
客户端拿到证书后,开始对证书中的内容进行验证,如果客户端计算出来的证书编号与证书中的证书编号相同,则验证通过:
上面的证书编号就是证书签名。
客户端如何获取第三方机构公钥
证书发布机构除了给别人发布证书外,他自己本身也有自己的证书。
这个证书发布机构的数字证书(一般由他自己生成)在操作系统刚安装好时(例如windows xp等操作系统),这些证书发布机构的数字证书就已经被微软(或者其它操作系统的开发机构)安装在操作系统中了,微软等公司会根据一些权威安全机构的评估选取一些信誉很好并且通过一定的安全认证的证书发布机构,把这些证书发布机构的证书默认就安装在操作系统里面了,并且设置为操作系统信任的数字证书。这些证书发布机构自己持有与他自己的数字证书对应的私钥,他会用这个私钥加密所有他发布的证书的指纹作为数字签名。
因为客户端接收到的证书中会写有颁发机构,客户端就根据这个颁发机构的值在本地找相应的公钥。
当然我们自己也可以成立证书发布机构,但是需要通过一些安全认证等等,只是有点麻烦。另外,如果数字证书只是要在公司内部使用,公司可以自己给自己生成一个证书,在公司的所有机器上把这个证书设置为操作系统信任的证书发布机构的证书(这句话仔细看清楚,有点绕口),这样以后公司发布的证书在公司内部的所有机器上就可以通过验证了(在发布证书时,把这些证书的Issuer(发布机构)设置为我们自己的证书发布机构的证书的Subject(主题)就可以了)。但是这只限于内部应用,因为只有我们公司自己的机器上设置了信任我们自己这个所谓的证书发布机构,而其它机器上并没有事先信任我们这个证书发布机构,所以在其它机器上,我们发布的证书就无法通过安全验证。
客户端如何获取数字证书
虽然数字证书由证书颁发机构颁发,但是客户端与服务器通信,再去证书颁发机构拿数字证书显然多此一举,影响交互速度。
首先服务器向证书颁发机构申请证书:
然后,证书颁发机构颁发证书给服务器管理员,管理员将证书上传服务器并配置,至此证书投入使用。
在客户端和服务器通信过程开始时会把证书发给客户端,客户端如何检查这个证书的确是合法的并且是真的服务器的证书呢?首先应用程序(客户端通信用的程序,例如IE、OUTLook等)读取证书中的发布机构,然后会在操作系统中受信任的发布机构的证书中去找该证书颁发机构的证书,如果找不到,那说明证书的发布机构是个水货发布机构,证书可能有问题,程序会给出一个错误信息。
如果在系统中找到了该证书颁发机构的证书,那么应用程序就会从证书中取出该证书机构的公钥,然后对与之通信的服务器证书里面的指纹和指纹算法用这个公钥进行解密,然后使用这个指纹算法计算证书的指纹,将这个计算的指纹与放在证书中的指纹对比,如果一致,说明证书肯定没有被修改过并且证书是该证书机构发布的,证书中的公钥肯定是服务器的。对方然后就可以放心的使用这个公钥和服务器进行通信了。
总结
HTTPS比HTTP多了很多次交互,因此HTTPS性能不会HTTp差,算是牺牲性能换安全。
前面讲述的一大堆工作都是为了让客户端与服务器端安全地协商出一个对称加密算法。这就是HTTPS中的SSL/TLS协议主要干的活。剩下的就是通信时双方使用这个对称加密算法进行加密解密。
HTTPS要使客户端与服务器端的通信过程得到安全保证,必须使用的对称加密算法,但是协商对称加密算法的过程,需要使用非对称加密算法来保证安全,然而直接使用非对称加密的过程本身也不安全,会有中间人篡改公钥的可能性,所以客户端与服务器不直接使用公钥,而是使用数字证书签发机构颁发的证书来保证非对称加密过程本身的安全。这样通过这些机制协商出一个对称加密算法,就此双方使用该算法进行加密解密。从而解决了客户端与服务器端之间的通信安全问题。