HTTP/HTTPS网络安全

HTTPS-密钥交换

2018-10-07  本文已影响236人  两三行代码

2.3 密钥交换

2.3.1 RSA密钥交换
 RSA密钥交换的过程十分直截了当。客户端生成预主密钥(46字节随机数),使用服务器公钥对其加密,将其包含在ClientKeyExchange消息中,最后发送出去。服务器只需要解密这条消息就能取出预主密钥。TLS使用的是RFC 3447定义的RSAES-PKCS-v1_5加密方案。

注意 因为RSA算法可以同时用于加密和数字签名,所以RSA密钥交换可以按照这种方式工作。其他流行的密钥类型,比如DSA(DSS)和ECDSA,只能用于签名。

 RSA密钥交换的简单性也是它最大的弱点。用于加密主密钥的服务器公钥,一般会保持多年不变。任何能够接触到对应私钥的人都可以恢复主密钥,并构建相同的主密钥,从而危害到会哈安全性。
 对目标的攻击并不需要实时进行,强大的对手可以制定长期行动。攻击者会揭露所有加密的流量,耐心等待有朝一日可以得到密钥。比如,计算机能力的进步使暴力破解成为可能;也可以通过法律强制力、政治高压、贿赂或强行进入使用该密钥的服务器取得密钥。只要密钥泄漏,就可以解密之前记录的所有流量了。
 TLS中其他常见的密钥交换方式都不受这个问题的影响,被称为支持前向保密。使用那些密钥交换时,每个连接使用的主密钥相互独立。泄漏的服务器密钥可以用于冒充服务器,但不能用于追溯解密任何流量。

2.3.2 Diffie-Hellman密钥交换
 Diffie-Hellman(DH)密钥交换是一种密钥协定的协议,它使两个团体在不安全的信道上生成共享密钥成为可能。

注意
以这种方式协商共享密钥时不会收到被动攻击的威胁,但主动攻击者却可以劫持通信信道,冒充对端。这就是DH交换通常与身份验证联合使用的原因。

 抛开算法的细节,DH的诀窍是使用了一种正向计算简单、逆向计算困难的熟悉函数,即使交换中某些因子已被知晓,情况也是一样。最恰当的类比示例是混色:如果有两种颜色,那么何容易将其混在一起得到第三种颜色;但是如果只有第三种颜色的话,就很难确定它究竟是由那两种颜色混合而成的。
 DH密钥交换需要6个参数;其中两个(dh_p和dh_g)称为域参数,有服务器选取。协商过程中国,客户端和服务器各自生成另外两个参数,相互发送其中一个参数(dh_YS和dh_Yc)到对端,再经过计算,最终得到共享密钥。
 临时Diffie-Hellman(ephemeral Diffie-Hellman,DHE)密钥交换中没有任何参数被重复使用。与之相对,在一些DH密钥交换方式中,某些参数是静态的,并被嵌入到服务器和客户端中。这样的话,密钥交换的结果是一直不变的共享密钥,就无法具备前向保密的能力。
 TLS支持静态DH密钥交换,但无人只用。在协商DHE套件时,服务器将其所有参数填入ServerDHParams块并发送:
struct{
opaque dp_p;
opaque dp_g;
opaque dp_Ys;
}ServerDHParams;
客户端响应并发送其公开参数(dh_Yc);
struct{
select(PublicValueEncoding){
case implicit:
/空的,当客户端公共参数嵌入其客户端时/
case explicit:
opaque dh_Yc;
}dh_public;
}ClientDiffieHellmanPublic;
当前使用的DH交换存在一下这些现实问题。

2.3.3 椭圆曲线Diffe-Hellman密钥交换
 临时椭圆曲线Diffie-Hellman(elliptic curve Diffie-Hellman,ECDH)密钥交换原理与DH相似,但它的核心使用来不同的数学基础。正如名称所示,ECDHE基于椭圆曲线(elliptic curve,EC)加密。
 ECDH密钥交换发生在一条由服务器定义的特定的椭圆曲线上。这条曲线代替了DH中域参数的角色。理论上,ECDH支持静态的密钥交换,但实际使用时,只使用了这种临时的变种(ECDH)。
 密钥交换由服务器发起,它选择一条椭圆曲线和公开参数(EC point)并提交:
struct{
ECParameters curve_params;
ECPoint public;
}ServerECDHParams;
 服务器可以为密钥交换明确指定任意一条曲线,但TLS并未使用这个功能。作为替代,在TLS中,服务器通过指定某个名称引用一条可能预先定义好参数的曲线(EC point):
struct{
ECCurveType curve_type;
select(curve_type){
case explicit_prime:
case explicit_char2:
case named_curve:
NamedCurve namedcurve;
};
}EcParameters;
然后客户端提交自己的公开参数。在那以后,就可以计算主密钥:
struct{
select(PublicValueEncoding){
case implicit:
case explicit:
ECPoint ecdh_Yc;
}ecdh_public;
}ClientECDiffieHellmanPublic;
使用预定义参数,以及ellipic_curve扩展(客户端可以提交支持的曲线),可以使用服务器选择一条双方都支持的曲线。你可以在2.12.3节中找到更多有关命名曲线的可用信息。
2.4 身份验证
 在TLS中,为了避免重复执行密码操作造成巨大的开销,身份验证与密钥交换紧紧捆绑在一起,大多数场景中,身份验证的基础是证书支持的公钥密钥(最常见的是RSA,有时也用ECDSA)。一旦证书验证通过,客户端就知道了使用的公钥。在此之后,客户端将公钥交给指定的密钥交换算法,并由它负责以某种方式使用公钥验证另一端。
 在RSA密钥交换的过程中,客户端生成一个随机值作为预主密钥,并以服务器公钥加密后发送出去。拥有对应私钥的服务器解码消息得到预主密钥。身份验证原理很清楚:只有拥有对应私钥的服务器才能取得预主密钥,构造正确的会话密钥,并生成正确的Finished消息。
 在DHE和ECDHE的交换过程中,服务器为密钥交换提供自己的参数,并使用自己的私钥签名。客户端持有对应的公钥(从已验证的证书中获得),可以验证参数是否真正出自期望的服务器。

注意
服务器参数是与客户端和服务器随机值连在一起进行签名的,而客户端和服务器随机值对于握手来说是唯一的。因而,即使签名是以明文方式发送的,它也只对当前握手有效,这意味者攻击者无法重用签名。Logjam攻击显示了这种将签名绑定在握手过程上面的弊端;主动网络攻击者可以同步产生这个随机值,并且在某些情况下再次利用服务器签名。

HTTPS权威指南-协议
HTTPS-TLS-加密详解

上一篇下一篇

猜你喜欢

热点阅读