苦行僧DH

博客园 首页 新随笔 联系 订阅 管理

HTTPS是什么

HTTPS全称Hypertext Transfer Protocol Secure,意为安全的超文本传输协议,简称HTTP安全版。

HTTPS在网络协议层级上位于TCP/IP协议之上,HTTP之下,跟HTTP的区别就是加入了SSL/TLS协议以确保数据安全。

他们的关系如下:

为什么需要加密

加密的原因是因为在HTTP的情况下,客户端与服务端之间数据的传输为明文,且没有认证机制,就会很容易出现数据泄露、数据篡改的情况。

我们简单的举例,假设服务器A要通过服务器B的代理程序访问到服务器C,使用HTTP协议,如下图

注意此时代理程序作为中转站,完全可以获取服务器A的请求数据,那么服务器C的响应也可以获取到,此时如果数据为明文的话,可以试想一下会有多么危险,这种情况下数据被篡改是轻而易举的。

在现在的情况下,我们再次设想,代理程序不仅可以获取到明文的数据,还可以很轻易的对请求和响应数据进行篡改。如下图

很显然,在我们未进行加密的情况下,这种情况很容易就会发生,这种情况被称之为中间人攻击。

而这里仅仅是存在一个代理的情况下就如此危险,而真实情况下,我们公网场景下的网络请求经过的设备是非常多的,如出口路由器、防火墙、出口网关、运行商等等,只要中间任意一个设备不怀好意,那我们就是待宰的羔羊。

总结来看,在我们自身程序没有做加密的情况下,HTTP方式的请求跟裸奔没有区别。

所以HTTP请求的加密至关重要,对于我们程序而言,是安全的基础保障。

从上述的总结来看,HTTP不安全主要体现在:数据泄露、数据篡改。而HTTPS就是来解决HTTP所遇到的这两个问题。

如果使用对称加密,是否可行?

如果通信的双方都持有没有其他任何人知道的密钥,使用密钥将请求和响应进行加密,那么数据就不会泄露了,因为中间方没有这密钥是解密不出来数据的。

但问题是,这个密钥要怎么让双方都知道?这个双方绝大多数情况下就是浏览器与服务器。而且密钥由哪一方面生成?如果由服务器方生成,生成后发送后浏览器,但此时发送密钥的过程仍然是明文的,这个密钥如果被中间方劫持的话,加密就没有意义了。

那么使用对称加密最大的问题就是,密钥被明文传输了,以致于数据泄露和篡改都未解决。

如果使用非对称加密,是否可行?

前面用对称加密最大的问题就是密钥被明文传输,且该密钥是加解密都可以用的。那么如果使用非对称加密的话,情况也许会有好转。

非对称加密指的是,双方拥有私钥和公钥,私钥加密后公钥解密,公钥加密后私钥解密,而公钥加密无法使用公钥解密。

此时如果服务器方拥有私钥并生成公钥,将公钥通过明文方式传输给浏览器,浏览器请求使用该公钥加密数据后请求,此时中间方无法解密数据。

这样好像只解决了浏览器请求服务器的数据泄露问题,因为服务器响应时是需要使用私钥加密数据的,如果在前面服务器传输给浏览器的公钥被劫持了,那么服务器通过私钥加密后的响应数据就会被中间方劫持的公钥解出来。我们想一下,服务器传给浏览器公钥的时候,解决了浏览器到服务器的数据泄露问题,那么如果浏览器也给服务器一个公钥的话,自然也就能解决服务器响应浏览器的数据泄露问题。如图

此时看起来是解决了数据泄露问题,但其实并未解决,先说一下现在遇到的性能问题后再来说仍存在的问题。

注意:非对称加密性能消耗比对称加密大很多,网上有人做过测试大约1500倍左右,如果全使用非对称加密,那么效率是非常慢的。

此时我们需要权衡一下,既然对称加密快,但无法解决泄露问题,非对称加密慢,但能解决泄露问题。

我们中和一下,使用非对称加密来传输他们用于对称加密的密钥,真正的数据使用对称加密来处理,那么就是如下的流程:

1、浏览器创建私钥A并生成公钥A,传递给服务器

2、服务器拿到公钥A后,创建私钥B并生成公钥B,传递给浏览器

3、然后浏览器用公钥B加密用于对称加密的密钥C,传递给服务器

4、服务器使用私钥B进行解密得到密钥C

5、然后浏览器与服务器之间使用密钥C对称加密中间数据即可。

6、注意此时中间方只有公钥A、公钥B,而我们的密钥C是通过公钥B加密的,中间方无法解密,则密钥C是安全的。

此时密钥C是安全不会存在泄露的,后续的对称加密自然也就安全了,这就是对称加密+非对称加密的组合

这样来看,性能问题也得到了改善,但即使这么复杂的玩法却出现了其他问题,也就是中间人攻击问题!

中间人攻击

前面对称加密+非对称加密确实看似解决了数据泄露问题,但这个操作在遇到中间人攻击的情况下,数据泄露仍然未被解决,而且数据篡改的问题也会体现出来。

不仅数据泄露但如果遇到了中间人攻击问题但却无法避免中间人攻击问题,如下图来解释中间人攻击的情况:

① 当服务器传给浏览器公钥A的时候,中间方劫持公钥A,并生成需要的公钥C传递给浏览器。

② 当浏览器传给服务器公钥B的时候,中间方挟持公钥B,并生成需要的公钥D传递给服务器。

③ 当浏览器发送请求时,则会使用前面得到的公钥C进行加密,此时中间方则使用已经生成好的私钥C解密,此时数据已经泄露,然后再使用劫持的公钥A重新加密数据并转发至服务器,此时数据已经被篡改

④ 相反服务器响应浏览器时也会有③步骤一样的问题。

这里问题的根源在于,服务器给浏览器公钥的时候,浏览器无法得知当前拿到的公钥是否为正确的,是否没有被篡改过?那么此时是否可以再将传输的公钥进行加密?如果这样做,就会造成一个循环了,无论如何都会有一个关键密钥处于明文传输过程中。

数字证书和数字签名

那么如果浏览器提前就知道了服务器的公钥,那么就可以避免问题,因为密钥不会进行明文传输,但这明显是不现实的。不现实的原因是互联网上的服务器很多,浏览器没有办法知道所有服务器的公钥。此时,CA机构的作用就体现出来,如图

他们的完整过程为:

​ 1、CA机构拥有非对称加密的私钥和公钥

​ 2、CA机构将证书信息使用私钥加密、然后组装成一份完整的证书颁发给服务器。这被称之为数字证书。

​ 3、不仅如此,CA机构颁发的证书信息中还存在签名信息,将证书信息进行hash用私钥加密,这被称之为数字签名。

​ 4、注意证书中不仅包含证书信息,还包含数字签名。

​ 5、在浏览器请求服务器的时候,服务器将证书(域名基本信息、颁发机构信息、公钥信息、有效期、序列号、签名算法、数字签名、扩展信息)传给浏览器。

​ 6、假设此时证书明文信息为A,签名为B,注意因为浏览器已经提前保留了CA机构的公钥信息,所以此时验签的过程为,浏览器使用预留的公钥对签名解密后得到C1,并将证书中明文信息进行hash得到C2,此时如果C1==C2,则说明当前证书是正确的,否则说明证书存在篡改的风险。不仅校验证书信息,还会校验证书信息中的域名站点信息、有效期是否符合要求。

​ 7、注意,到这一步时证书是不可被篡改的,因为验签是浏览器使用系统内置的CA机构公钥,中间人无法修改这一事实。

​ 8、浏览器验证证书完成后,随机生成一个随机数X,并使用证书中公钥加密后发送给服务器。注意此时中间人无法得知密钥真实内容,因为它没有证书中私钥信息。

​ 9、服务器使用证书的私钥解密浏览器传递过来的随机数X。

​ 10、注意浏览器和服务器都会使用 随机数X+密钥导出算法 计算出随机数Y。

​ 11、然后基于随机数Y,双方各自利用算法生成对称加密的密钥M,然后浏览器与服务器之间传输数据都是用密钥M进行对称加密操作的。

​ 12、除了使用密钥M对称加密传输的数据以外,还会使用密钥M对原数据包进行签名,得出HMAC值,该值用于校验数据包完整。

以上就是加入了CA机构后,完整的HTTPS数据加密和交互流程,那么又会有如下的疑问:

浏览器从哪得知的这些CA机构

不是浏览器保留的,这些CA机构是由系统自身预留的,正经系统都是有预留的

如何保证证书是合法的?

如果不是被系统信任的机构颁发的证书,那么就无法使用系统预留的CA公钥信息验签成功,自然就可以确认证书合法性了。

而此时中间人如果想修改、掉包证书信息都不现实,如果修改则验签失败,如果掉包则浏览器预留的公钥解密不出来,自然验签也失败!

服务器的证书中公钥信息是明文传输给浏览器的,中间人拿到这个公钥信息后是否有风险?

注意,这个公钥信息的主要作用是加密随机数X后传递给服务器,服务器会使用私钥解密,然后双方使用相同的规则生成对称加密的密钥。这里中间人只要没有私钥信息,那么就无法得知当前的随机数X,哪怕是中间人将随机数X改了,那么导致的结果就是浏览器与服务器各自生成的密钥不一致,进而导致后续数据传输出错中止。这里最重要的就是欺负中间人没有证书私钥,在这种情况下,中间人无法解密数据,如果篡改数据则会造成浏览器与服务器双方出现错误,进而在这个时候解决了数据泄露和篡改问题。

浏览器与服务器之间传输数据时,怎么验证数据完整性

首先我们要知道,双方的数据交互是使用对称加密的,密钥M,除此之外,还会使用密钥M对原数据包进行签名得出HMAC值,另一方同样的验签即可保证数据完整性

如果证书错误,对于浏览器而言,会发生什么?

假如我们自己搞一个免费证书,这个证书被浏览器拿到后,由于不是操作系统所预留的CA机构证书,所以很可能导致他们浏览器对证书的校验失败,那么则会弹出红色方框提示,严格的浏览器甚至不允许访问此类网站。这是证书不被信任的情况。

如果证书信息中包含的网站域名信息跟当前访问的域名不一致,则浏览器也会提示。

证书文件有哪些?丢失了怎么办

证书文件(.crt、.cer、.pem)等:这里防止证书基本信息,例如公钥信息、网站信息等

私钥文件(.key、.pem)等:这里面放的是证书的私钥文件

其他还有两种文件,不过不重要。

这里,如果将证书文件丢了无所谓,因为本身这个文件就是明文传输给浏览器的,而私钥文件不能丢,注意前面我们说了中间人束手无策的根本原因是因为重要的加密参数都使用了非对称加密且中间人因为没有私钥所以无法解密。如果此时将私钥交给中间人的话,那么就给中间人提供了泄露数据、篡改数据的钥匙。

注意,其实很多防火墙、网闸等中间网络设备如果没有对应网站的https证书的话,他们也是无法解析中间数据的。

HTTPS 一定安全吗?

HTTPS虽然采用数字证书+数字签名,并采用非对称加密和对称加密等一系列算法实现防泄露、防篡改,但并不能说就完全安全了。

1、假如你的网站是www.abc.com,而中间人能拿到www.abc.com的证书文件,那么中间人就可以伪造你的网站,进行中间人攻击了。

2、如果你的网站存在安全漏洞使攻击者可以绕过HTTPS,那也会不安全

3、如果浏览器所处的系统感染了木马,那么木马也可以拿到你网站所对应CA机构的公钥信息,那么你们中间交互的数据很自然的就可以被解开。

4、如果你的网站感染了木马或钓鱼程序,那么你的证书等信息很容易就会被获取到,自然就不安全了。

所以总结来看,HTTPS只是保证了网络传输时的安全,并不能代表完全安全,我们除了HTTPS以外,证书安全、系统漏洞、服务器安全等都至关重要!

为什么证书的签名要将证书信息hash后再私钥加密,不直接加密?

1、减小签名数据的大小:需要签名的证书信息是比较大的,包含了域名基本信息、颁发机构信息、公钥信息、有效期、序列号、签名算法、数字签名、扩展信息等,所以hash后可以将证书信息压缩为较小的数据,提高签名速度。

2、防止篡改:如果证书信息被篡改后,hash后的值固然会变化,那么验签也就失败了

HTTPS的密钥传输与计算是什么时候进行的?

注意浏览器请求服务器的时候,只有第一次请求时会进行证书传递、密钥计算等操作,因为这些操作本身比较耗时。

然后浏览器会维护一个sessionId,服务器也会维护一个相同的sessionId,后续浏览器携带该sessionId进行请求即可,就不必反复传递和计算密钥。

posted on 2024-04-27 00:11  苦行僧DH  阅读(74)  评论(0编辑  收藏  举报