Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSL/TLS通信 #31

Open
zhangyachen opened this issue Mar 2, 2016 · 1 comment
Open

SSL/TLS通信 #31

zhangyachen opened this issue Mar 2, 2016 · 1 comment
Labels

Comments

@zhangyachen
Copy link
Owner

zhangyachen commented Mar 2, 2016

复习基本概念

  • 对称密码:加密和解密使用同一密匙。
  • 公钥密码:加密和解密使用不同密钥的方式。
  • 单向散列函数:计算散列值,保证的不是机密性,而是完整性。
  • 消息认证码:确认消息是否被篡改,而且能够确认消息是否来自所期待的通信对象。
  • 数字签名:由于消息认证码使用公钥进行加密的,会出现发送方否认的情况,所以为了防止这种情况出现,发送方使用私钥进行加密散列值。
  • 证书:我们必须保证验证数字签名的公钥必须属于发送方,否则数字签名会失效。为了确认自己得到的公钥是否合法,我们需要使用证书。

密码技术

什么是SSL/TLS

来看一下通过http发送请求的场景:

image

但是此种情况下,信用卡号就很有可能被窃听。于是,我们可以使用SSL或者TLS作为对通信进行加密的协议,然后在此之上承载http。通过对此两种协议的叠加,我们就对HTTP的通信进行加密,防止窃听。

image

以上面的例子为例,如果我们想要达到安全的通信,必须达到以下几点:

  • 信用卡号不被窃听
  • 信用卡号不被篡改
  • 确认通信对方是真实的而不是假冒的

以上问题抽象出来就是:

  • 机密性
  • 完整性
  • 认证问题

通过文章最开始提到的密码技术,我们可以想到机密性可以用对称密码解决(这里的窃听不是指发送内容不能被攻击者得到,而是攻击者即使得到发送内容也不能理解或者破译)。由于对称密码不能被攻击者预测,因此我们使用伪随机数生成器来生成密钥。若要将对称密码的密钥发送给通信方而不被攻击者窃听,可以使用公钥密码或者Diffie-Hellman密钥交换。
识别篡改可以使用消息认证码技术.
对通信对象的认证,可以使用对公钥加上数字签名所生成的证书。

我们需要一个“框架”将上述工具组合起来,SSL/TLS协议就扮演了这样一个框架的角色。

上面的例子是SSL/TLS承载HTTP协议,其实SSL/TLS还可以承载很多协议,例如:SMTP、POP3。

image

SSL与TLS的区别

SSL是1994年网景公司设计的一种协议,并在该公司的Web浏览器中进行了实现。随后很多Web浏览器都采用了这一种协议,使其成为了事实上的行业标准。SSL已经于1995年发布了3.0版本。
TLS是IETF在SSL3.0的基础上设计的协议。在1999年作为RFC2246发布的TLS1.0,实际上相当于SSL3.1。

为什么使用SSL/TLS

  • 所有信息都是加密传播,第三方无法窃听。
  • 具有校验机制,一旦被篡改,通信双方会立刻发现。
  • 配备身份证书,防止身份被冒充。

SSL/TLS的层次化协议

TLS协议分为TLS记录协议和TLS握手协议。位于底层的TLS记录协议负责进行加密,位于上层的TLS握手协议负责加密以外的其他操作。而上层的TLS握手协议又分为4个子协议。

image

记录协议

负责消息的压缩、加密以及数据的认证。
image
处理过程如下:

  • 将消息分割成小片段,然后对每个片段进行压缩,压缩算法需要与通信对象进行协商。
  • 将每个压缩的片段加上消息认证码,这是为了保证完整性并进行数据的认证。通过附加消息的MAC值,可以识别出篡改。与此同时,为了防止重放攻击,在计算消息认证码时,还加上了片段的编号,单向散列函数的算法。以及消息认证码所使用的共享密钥都需要与通信对象协商决定。
  • 经过压缩的片段加上消息认证码会一起通过对称密码进行加密。加密使用CBC模式,CBC的初始化向量(IV)通过主密码(master secret)生成,而对称密码的算法以及共享密钥需要协商。
  • 上述的加密数据再加上数据类型、版本号、压缩后的长度组成的报头就是最终的报文数据。

握手协议

负责生产共享密钥以及交换证书。
握手协议主要分为4个子协议:握手协议、密码规格变更协议、警告协议和应用数据协议。

握手协议

负责在客户端和服务器之间协商决定密码算法和共享密钥。基于证书的认证也在这一步完成。这段协议相当于下面的会话:
客户端:“你好,我能理解的密码套件有RSA/3DES,或者DSS/AES,请问我们使用哪一种?”
服务器:“你好,我们使用RSA/3DES吧,这是我的证书。”
协商之后,就会互相发出信号来切换密码。负责发出信号的就是下面介绍的密码规格变更协议。

密码规格变更协议

负责向通信对象传达变更密码方式的信号。
客户端:“我们按照刚才的约定切换密码吧。1,2,3”
中途发生错误时,就会通过下面的警告协议传达给对方。

警告协议

负责向通信对象传达变更密码方式的信号。
客户端:“我们按照刚才的约定切换密码吧。1,2,3”
中途发生错误时,就会通过下面的警告协议传达给对方。

警告协议

服务器:“刚才的消息无法正确解析哦。”

应用数据协议

将TLS上面承载的应用数据传达给通信对象的协议。

使用SSL/TLS进行通信

image
image
(图片太长了,截了两次,o(╯□╰)o)

一些重要握手过程:

ClientHello

客户端向服务器发出加密通信的请求。
在这一步,客户端主要向服务器提供以下信息。

  • 支持的协议版本,比如TLS 1.0版。
  • 当前时间
  • 一个客户端生成的随机数,稍后用于生成"对话密钥"。
  • 会话ID
  • 支持的加密方法,比如RSA公钥加密。
  • 支持的压缩方法。

“会话ID”是当客户端和服务器希望重新使用之前建立的会话(通信路径)时所使用的信息。

ServerHello

服务器收到客户端请求后,向客户端发出回应。服务器的回应包含以下内容。

  • 确认使用的加密通信协议版本,比如TLS 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信。
  • 一个服务器生成的随机数,稍后用于生成"对话密钥"。
  • 当前时间
  • 会话ID
  • 确认使用的加密方法,比如RSA公钥加密。
  • 密码套件。

Certificate

服务器发送Certificate消息。包含以下内容

  • 证书清单
    首先发送的是服务器的证书,然后会按顺序发送对服务器证书签名的认证机构的证书。
    当以匿名方式通信时,不发送Certificate消息。

ServerKeyExchange

当Certificate消息不足以满足需求时(例如匿名方式通信),服务器会通过ServerKeyExchange消息向客户端发送一些必要信息。
当使用RSA时,服务器发送N与E,也就是公钥。
当使用DH算法时,服务器发送P、G、G的x次方modP(DH算法的公开参数)

ClientKeyExchange

客户端从服务器的证书中取出服务器的公钥,然后向服务器发送以下信息。

  • 一个随机数。该随机数用服务器公钥加密,防止被窃听。该随机数也叫作pre-master key。有了它以后,客户端和服务器就同时有了三个随机数,接着双方就用事先商定的加密方法,各自生成本次会话所用的同一把主密码。而主密码用来加密客户端和服务器的通信内容。
    当使用RSA时,会随ClientKeyExchange一起发送经过加密的预备主密码。
    当使用DH算法时,会随ClientKeyExchange一起发送DH的公开值,即Y(G的x次方模P),之后双方也能算出相同的pre-master key。

主密码

非常重要的一个数值,TLS密码通信的机密性和数据的认证全部依靠这个数值。

主密码的计算

主密码依赖如下信息计算出来:

  • 预备主密码
  • 客户端随机数
  • 服务器随机数

当使用RSA公钥密码时,客户端在发送ClientKeyExchange消息时,将经过加密的预备主密码一起发送给服务器。
当使用DH密钥交换时,客户端在发送ClientKeyExchange消息时,将DH的公开值一起发送给服务器。根据这个值,客户端和服务器会各自生成预备主密码。
当根据预备主密码计算主密码时,会使用两个单向散列函数(MD5和SHA-1)组合而成的伪随机数生成器。之所以用两个单向散列函数,是为了提高安全性。
image

为什么一定要三个随机数

引用dog250的理解

不管是客户端还是服务器,都需要随机数,这样生成的密钥才不会每次都一样。由于SSL协议中证书是静态的,因此十分有必要引入一种随机因素来保证协商出来的密钥的随机性。
对于RSA密钥交换算法来说,pre-master-key本身就是一个随机数,再加上hello消息中的随机,三个随机数通过一个密钥导出器最终导出一个对称密钥。
pre master的存在在于SSL协议不信任每个主机都能产生完全随机的随机数,如果随机数不随机,那么pre master secret就有可能被猜出来,那么仅适用pre master secret作为密钥就不合适了,因此必须引入新的随机因素,那么客户端和服务器加上pre master secret三个随机数一同生成的密钥就不容易被猜出了,一个伪随机可能完全不随机,可是是三个伪随机就十分接近随机了,每增加一个自由度,随机性增加的可不是一。

主密码的目的

主密码用于生成下列6种信息:

  • 对称密码的密钥(客户端->服务器)
  • 对称密码的密钥(客户端<-服务器)
  • 消息认证码的密钥(客户端->服务器)
  • 消息认证码的密钥(客户端<-服务器)
  • 对称密码的CBC模式所使用的初始化向量(客户端->服务器)
  • 对称密码的CBC模式所使用的初始化向量(客户端<-服务器)

SSL/TLS密码技术小结

image

对SSL/TLS的攻击

  • 对各个密码技术的攻击,比如对称密码。但是,SSL/TLS并不依赖于某种密码组件,当发现某种对称密码存在弱点时,换一种对称密码即可。
  • 对伪随机数进行攻击。
  • 利用证书的时间差进行攻击。
    要验证证书必须使用CRL(证书作废清单)。如果客户端没有安装最新版的CRL,那么SSL/TLS也无法保证通信的安全。

TLS握手优化

这部分还没涉猎过,先找个文章mark下。
https://imququ.com/post/optimize-tls-handshake.html

参考资料:《图解密码技术》
http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html
http://www.ruanyifeng.com/blog/2014/09/illustration-ssl.html

@anfa1014
Copy link

anfa1014 commented Nov 3, 2018

thx!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants