整理TLS(SSL)协议关键步骤(上)

HTTP不安全问题

前面复习总结了数据加密算法保证数据安全不泄露,消息验证码MAC算法保证数据没有被篡改,还有公开密钥算法三种用途,加密解密,密钥协商,身份验证。上面这些方案,算法都是TLS协议的一部分,用来解决HTTP不安全的问题。这篇日志把上面这些东西整理下,看看TLS/SSL协议在开始到结束的身份认证,密钥协商和数据加密步骤如何一步一步保证HTTP安全的。TLS/SSL协议既然是用来解决HTTP不安全问题,那么先来总结下HTTP几个核心的不安全原因。

  1. 没有身份验证

HTTP使用TCP/IP协议传输报文,TCP协议只保证数据能正确传送到通信双方处,在C/S模式下,对于服务器来说,只要接收到的HTTP请求格式是正确的,就会响应该请求,不做身份验证的话服务器不知道这条请求是谁发来的,对于客户端也一样,客户端访问服务器主机www.badui.com,请求发送出去后,可能经过很多中间设备,如网关服务器,中间就可能会受到“中间人攻击”,最终访问到的是www.badui.cn。还有就是不可抵赖性问题,在多人通信中,大家持有相同的密钥进行加密和解密,假设B收到A发送的一条消息,但A抵赖了,说消息不是他发送的,是C发送的,因为C也有共同的密钥,C也可以加密数据后发送给B,所以A可以抵赖。同理还有第三方证明问题,假如A发送了一条消息给B,但B无法向D证明这条消息是A发送的,原因是C也有共同的密钥,C也可以向B发消息,所以B无法向D证明这条消息是来自A的还是C的。

所以说如果不去验证消息发送方的身份的话,会出现一系列不可靠不安全的问题。

 

  1. 数据没有加密

HTTP是明文传输的,并不会对消息进行加密,TCP/IP发送报文会经过很多个路由节点,如果中途消息被截获了,那么你的信息就泄露了。TLS/SSL使用对称加密或者公开密钥算法保证数据的安全。

 

  1. 没有验证数据篡改

上面说到,HTTP数据传输过程可能会经过很多个路由节点,中途某个节点如果消息被截获了,可能被攻击者修改原始数据,再进行转发,且由于HTTP使用的TCP/IP协议不进行身份验证,造成的问题是服务器端和客户端接收到请求后,只要格式正确,消息内容完整,都会以为该消息是正确的,原始的数据。解决方法就是使用消息验证码,给发送的消息用共同的密钥计算出一个MAC值,随消息一起发送,接收方使用共同的密钥对消息进行计算得到MAC值,再与一起发送来的MAC值做比较,一致则认为消息没有被篡改过。

HTTP与TLS/SSL

应用层协议HTTP中引入TLS/SSL协议,在任何应用层数据到达传输层TCP/IP之前,都会先由TLS/SSL协议“加工”处理,将HTTP和TLS/SSL结合在一起就是我们现在常见的HTTPS,对于HTTP Web服务器,默认是监听端口号80上的HTTP请求,如果支持HTTPS,则默认监听端口号443上的HTTPS请求。总的来说,TLS/SSL协议是单独的模块,单独的协议,在应用层上的协议都可以使用它。

 

TLS/SSL加密协议步骤总结

前面说到的密钥协商,数据加密,消息验证和身份验证,都是TLS/SSL协议的一部分,目的是解决HTTP不安全的问题,除此之外,还需要使用PKI技术来解决中间人攻击问题,下面就来按顺序整理整个TLS/SSL协议的运作过程。

密钥协商-动态密钥

通信双方建立连接时需要协商出共同的密钥,这个过程十分重要,因为密钥用来进行消息的加密和解密,如果密钥协商中途泄露了关键信息,那么前面协商出的密钥就白费了。你可能会想,使用像静态密钥的方式,通信双方事前就存储好共同的密钥,一直使用它来加密解密不就可以了吗,何必每次建立连接时都去协商一个新的密钥呢?对于C/S模式下,服务器通常要处理许多许多的客户端请求,如果服务器给每一个客户端都分配一个固定不变的密钥,那么对于服务器端的数据库存储量会越来越大,且一旦服务器端密钥泄露,造成的后果就是所有与这些客户端通信的密钥都泄露了。所以需要使用动态密钥(或者说会话密钥)的方式,也就是每次通信连接建立时协商出本次通信的密钥,通信结束后密钥就被丢弃。

在客户端和服务器端建立连接时,先使用密钥协商算法商量出预备主密钥,预备主密钥再通过同样的密码衍生算法转换出主密钥。前面讲到密钥协商的一般有两种方式,RSA和DH密钥协商。

RSA密钥协商

RSA密钥协商步骤大致如下:

  1. 客户端发送连接请求给服务器端,服务器端接收到请求后,将自己的密钥对中公钥部分发送回客户端。
  2. 客户端接收到服务器端公钥后,自己使用随机数生成器生成一个预备主密钥,然后使用服务器公钥对预备主密钥进行加密,再发送回给服务器端。此时由于中间方没有服务器端私钥,所以即使拦截了加密后的预备主密钥,也没办法解密。
  3. 服务器端接收到客户端回应后,使用自己的私钥解密出预备主密钥,完成密钥协商。

不过RSA密钥协商有些不足是,预备主密钥其实完全是由客户端决定的,服务器端只是提供公钥给客户端进行加密,安全传输预备主密钥而已,假设客户端生成的预备主密钥安全性不高,那么中间方完全可以在截获了被加密的预备主密钥后,直接对其进行破解尝试,而不需要去破解服务器端的私钥。

DH密钥协商

DH密钥协商则完全是由通信双方共同参与协商的过程,通信双方各自保留一部分信息,并通过互相交换这部分信息,一起协商得到预备主密钥,即使中途某一部分参数信息别截获,也没办法依靠这一部分信息计算出预备主密钥。DH密钥协商用到的DH参数由通信双方任意一方生成都可以,这里假设在服务器端生成,过程大致如下:

  1. 客户端发送建立请求,服务器端接收后,生成一个RSA密钥对,DH参数和DH密钥,并将RSA公钥发送给客户端。
  2. 服务器端使用RSA私钥签名DH参数和服务器DH公钥,和签名值,三个一起发送给客户端。
  3. 客户端通过服务器端的RSA公钥验证签名值,并解密得到DH参数和服务器端DH公钥。
  4. 客户端通过DH参数生成客户端的DH密钥对,然后将客户端DH公钥发送给服务器端。
  5. 此时服务器端持有的信息有:服务器端RSA密钥,DH参数和DH密钥客户端DH公钥。客户端持有信息有:服务器端RSA公钥,服务器端DH参数和DH公钥,自己的客户端DH密钥
  6. 最后,服务器端使用自己的DH私钥和客户端的DH公钥计算出预备主密钥。客户端使用自己的DH私钥和服务器端的DH公钥计算出预备主密钥。完成密钥协商。

从上述过程可以看到,通信双方协商密钥时,必须互相发送参数,客户端需要服务器DH公钥,服务器端需要客户端公钥,然后再和各自自己的DH私钥计算出预备主密钥。即使中间双方的DH公钥都泄露了,也没办法计算出预备主密钥,并且密钥只在本次通信有效,会话结束后密钥就会失效,提供了前向安全性,什么是前向安全性?下一篇日志说。

你可能感兴趣的:(网络工程)