SSL协商
由于非对称加密的速度比较慢,所以它一般用于密钥交换。双方通过公钥算法协商出一份密钥,然后通过对称加密来通信。当然,为了保证数据的完整性,在加密前要先经过HMAC的处理。
不管何种密钥交换体系都是为了获得共同通信用的对称加密密钥,并且拥有共同的SSL Session ID。
SSL缺省只进行server端的认证,客户端的认证是可选的。
以下是其流程图:
简单的说
SSL客户端(也是TCP的客户端)在TCP链接建立之后,发出一个ClientHello来发起握手,这个消息里面包含了自己可实现的算法列表和其它一些需要的消息,SSL的服务器端会回应一个ServerHello,这里面确定了这次通信所需要的算法,然后发过去自己的证书(里面包含了身份和自己的公钥)。Client在收到这个消息后会生成一个秘密消息,用SSL服务器的公钥加密后传过去,SSL服务器端用自己的私钥解密后,会话密钥协商成功,双方可以用同一份会话密钥来通信了。
密钥协商的形象化比喻
如果上面的说明不够清晰,这里我们用个形象的比喻,我们假设A与B通信,A是SSL客户端,B是SSL服务器端,加密后的消息放在方括号[]里,以突出明文消息的区别。双方的处理动作的说明用圆括号()括起。
A:我想和你安全的通话,我这里的对称加密算法有DES,RC5,密钥交换算法有RSA和DH,摘要算法有MD5和SHA。
B:我们用DES-RSA-SHA这对组合好了。
这是我的证书,里面有我的名字和公钥,你拿去验证一下我的身份(把证书发给A)。
目前没有别的可说的了。
A:(查看证书上B的名字是否无误,并通过手头早已有的CA的证书验证了B的证书的真实性,如果其中一项有误,发出警告并断开连接,这一步保证了B的公钥的真实性)
(产生一份秘密消息,这份秘密消息处理后将用作加密密钥,加密初始化向量和hmac的密钥。将这份秘密消息(协议中称为pre_master_secret)用B的公钥加密,封装成称作ClientKeyExchange的消息。由于用了B的公钥,保证了第三方无法窃听)
我生成了一份秘密消息,并用你的公钥加密了,给你(把ClientKeyExchange发给B)
注意,下面我就要用加密的办法给你发消息了!
(将秘密消息进行处理,生成加密密钥,加密初始化向量和hmac的密钥)
[我说完了]
B:(用自己的私钥将ClientKeyExchange中的秘密消息解密出来,然后将秘密消息进行处理,生成加密密钥,加密初始化向量和hmac的密钥,这时双方已经安全的协商出一套加密办法了)
注意,我也要开始用加密的办法给你发消息了!
[我说完了]
A: [我的秘密是…]
B: [其它人不会听到的…]
加密的计算
如何利用加密密钥,加密初始化向量和hmac的密钥来加密消息:
1 借助hmac的密钥,对明文的消息做安全的摘要处理,然后和明文放到一起。
2 借助加密密钥,加密初始化向量加密上面的消息。
秘钥交换
密钥交换算法:
常用的密钥交换算法
- dh_anon: Diffie-Hellman(DH)密钥交换,未经身份验证
- dhe_rsa: 临时DH密钥交换,使用RSA身份验证
- ecdh_anon: 临时椭圆曲线DH(elliptic curve DH,ECDH)密钥交换,未经身份验证
- ecdhe_rsa: 临时ECDH密钥交换,使用RSA身份验证
- ecdhe_ecdsa: 临时ECDH密钥交换,使用ECDSA身份验证
- krb5: Kerberos密钥交换
- rsa: RSA密钥交换和身份验证
- psk: 预共享密钥(pre-shared key,PSK)密钥交换和身份验证
- dhe_psk: 临时DH密钥交换,使用PSK身份验证
- rsa_psk: PSK密钥交换,使用RSA身份验证
- srp: 安全远程密码(secure remote password,SRP)密钥交换和身份验证
接下来讲讲 RSA 和 DH(Diffie-Hellman)。
RSA 密钥交换协议
DH 密钥交换协议
迪菲-赫尔曼密钥交换(Diffie–Hellman key exchange,简称"D–H”) 是一种安全协议。
它可以让双方在完全没有对方任何预先信息的条件下通过不安全信道建立起一个密钥。这个密钥可以在后续的通讯中作为对称密钥来加密通讯内容。
DH parameter
参考Diffie-Hellman_parameters - openssl,这个参数是在服务端配置用来使用 perfect forward secrecy 的。
算法描述
离散对数的概念:
原根:如果 a 是素数 p 的一个原根,那么数值:
a mod p,a^2 mod p,…,a^(p-1) mod p
是各不相同的整数,且以某种排列方式组成了从 1 到 p-1 的所有整数。
离散对数:如果对于一个整数 b 和素数 p 的一个原根 a,可以找到一个唯一的指数 i,使得:
b =(a^i)mod p 其中 0 ≦ i ≦ p-1
那么指数 i 称为 b 的以 a 为基数的模p的离散对数。
Diffie-Hellman算法的有效性依赖于计算离散对数的难度,其含义是:当已知大素数 p 和它的一个原根 a 后,对给定的 b,要计算 i,被认为是很困难的,而给定 i 计算 b 却相对容易。
Diffie-Hellman算法:
假如用户A和用户B希望交换一个密钥。
取素数 p 和整数 a,a 是 p 的一个原根,公开 a 和 p。
A选择随机数XA<p,并计算YA=a^XA mod p。
B选择随机数XB<p,并计算YB=a^XB mod p。
每一方都将X保密而将Y公开让另一方得到。
A计算密钥的方式是:K=(YB) ^XA mod p
B计算密钥的方式是:K=(YA) ^XB mod p
证明:
(YB) ^ XA mod p
= (a^XB mod p) ^ XA mod p
= (a^XB) ^ XA mod p
= (a ^ XA) ^ XB mod p (<– 最终加密密钥即为 a^(XA*XB) mod p)
= (a^XA mod p) ^ XB mod p = (YA) ^XB mod p
由于XA和XB是保密的,而第三方只有 p、a、YB、YA可以利用,只有通过取离散对数来确定密钥,但对于大的素数p,计算离散对数是十分困难的。
例子:
假如用户Alice和用户Bob希望交换一个密钥。
取一个素数p=97和97的一个原根a=5。
Alice和Bob分别选择秘密密钥XA=36和XB=58,并计算各自的公开密钥:
YA=a^XA mod p = 5^36 mod 97=50
YB=a^XB mod p = 5^58 mod 97=44
Alice和Bob交换了公开密钥之后,计算共享密钥如下:
Alice:K=(YB) ^XA mod p =44^36 mod 97=75
Bob:K=(YA) ^XB mod p =50^58 mod 97=75
安全性
当然,为了使这个例子变得安全,必须使用非常大的XA, XB 以及 p, 否则可以实验所有的可能取值。(总共有最多97个这样的值, 就算XA和XB很大也无济于事)。
如果p是一个至少 300 位的质数,并且XA和XB至少有100位长, 那么即使使用全人类所有的计算资源和当今最好的算法也不可能从 a, p 和 a^(XAXB) mod p中计算出 XAXB。
这个问题就是著名的离散对数问题。注意g则不需要很大, 并且在一般的实践中通常是2或者5。
SSL的安全性和中间人攻击
非对称加密
非对称加密的两把钥匙可以在两种信息形式之间转换。可以用公钥加密私钥解密,也可以用私钥加密公钥解密。
前一种用作加密信息,后一种用作数字签名。数字签名保证了收到的信息不是来自中间人伪造的,代价是消息是公开的。
中间人攻击
一个中间人攻击能成功的前提条件是攻击者能将自己伪装成每一个参与会话的终端,并且不被其他终端识破。中间人攻击是一个(缺乏)相互认证的攻击。
其他相关的应对措施:
- SSL的证书认证,并且可以双向验证。
- 更强力的相互认证,如密码
- 用慢哈希函数做延迟测试
- 一次性密码本
CA证书
CA 是英文 Certification Authority (认证机构)的缩写。
中间人攻击者可以解密(读取和存储)任何一个人的信息并重新加密信息,然后传递给另一个人。
因此通常都需要一个能够验证通讯双方身份的机制来防止这类攻击。例如当Alice和Bob共有一个公钥基础设施时,他们可以将他们的返回用密钥进行签名,由接收端用公钥解开并进行验证。
这一类设施称作公开密钥基础设施(PKI)。
证书链的验证过程:父证书机构用私钥加密子证书的公钥一起其他信息,浏览器拿到父证书的公钥解密子证书的数字签名,里面包含子证书的公钥,进行对比即可。
SSL安全性分析
对于 RSA 密钥交换
对于RSA密钥交换算法来说,Premaster secret 本身就是一个随机数,再加上hello消息中的随机,三个随机数通过一个密钥导出器最终导出一个对称密钥。
但 Premaster secret 是由客户端生产,并由服务端公钥加密后传输的。它的安全性来自于非对称加密的安全性。
尽管如此,中间人也可以发送自己伪造的公钥,用对应的伪造私钥签名消息。所以,必须通过CA证书链确保公钥是确实来自通信的对方。
对于 DH 密钥交换
DH密钥交换在RSA密钥交换的基础(RSA非对称加密,可靠的服务端公钥验证)上增加算法破解的难度。
对于 dh,包括 ecdh 算法(不考虑匿名dh和临时dh),就只有hello消息中的两个随机数因子了。
以这种方式协商共享密钥时不会受到被动攻击的威胁,但不能预防主动的中间人攻击。它的安全性来自于离散对数的计算难度,而且也同样需要CA认证来防止中间人攻击。
为什么需要 DH 密钥交换算法
SSL定义了一系列密码套件,这些套件分别使用了RSA、DH、DHE(EDH,临时DH)、ECDH(椭圆曲线版DH)作为密钥交换算法,而前两者和后两者的区别就是后两者支持前向安全(Forward Secrecy,缩写:FS),有时也被称为完美前向安全(英语:Perfect Forward Secrecy,缩写:PFS)。
用来产生会话密钥(session key)的长期密钥(long-term key)泄露出去,不会造成之前通讯时使用的会话密钥(session key)的泄露,也就不会暴漏以前的通讯内容。
ssl_ciphers
openssl 支持的加密套件:
❯ openssl ciphers
ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:GOST2012256-GOST89-GOST89:DHE-RSA-CAMELLIA256-SHA256:DHE-RSA-CAMELLIA256-SHA:GOST2001-GOST89-GOST89:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA256:CAMELLIA256-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-CAMELLIA128-SHA256:DHE-RSA-CAMELLIA128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:CAMELLIA128-SHA256:CAMELLIA128-SHA:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:RC4-SHA:RC4-MD5:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:DES-CBC3-SHA
ECDHE-ECDSA-AES256-GCM-SHA384
代表着:
- ECDHE 算法进行非对称加密
- ECDSA 进行证书验证
- 265bit AES 对称加密
- GCM:块加密的一种操作模式,有着比较好的性能
- 384bit SHA 数据加密算法
Cloudflare 的 Keyless SSL
Keyless SSL lets sites use Cloudflare’s SSL service while retaining on-premise custody of their private keys. This is a brand-new security technology, developed by a team of cryptographers, systems engineers, and network specialists at Cloudflare.
The standard Cloudflare SSL service requires a customer to share their site’s SSL key with Cloudflare. Cloudflare takes extensive technical measures to safeguard customer key information. However, for some customers there are policy or technical obstacles preventing them from sharing their site’s SSL key with Cloudflare. This is why we are excited to introduce Keyless SSL.
浏览器安全性
浏览器知道你的用于RSA的Premaster secret,和用于DH的Client secret,见 Your Browser Knows All Your Secrets。