DTLS 密钥协商

理解基本加密知识

对称与非对称

(一)什么是对称加密?

对称加密算法中,数据发送方将“明文”和“密钥”一起经过特殊“加密算法”处理成密文后,将它发送出去。

接收方收到密文后,若想解读原文,则需要使用加密用到的相同“密钥”及相同“解密算法”对“密文”进行解密,才能使其恢复成原文。

它的最大优势是加解密速度快,适用于大数据量进行加密,缺点是密钥管理困难。

最典型的问题就是如何同步这个密钥,同步过程如果在公网上,不进行加密是可以抓包拿到的,那么这里就遇到了要对密钥加密的问题。

常见的对称加密算法有 AES、DES、Blowfish 等等。

对称加密的核心是:只有一把密钥。

简单描述就是:明文需要通过密钥进行加密,又通过该密钥进行解密,这样的话自己负责加密,别人负责解密。

(二)什么是非对称加密?

非对称加密算法中,有两个密钥:公钥和私钥。它们是一对,如果用公钥进行加密,只有用对应的私钥才能解密;如果用私钥进行加密,只有用对应的公钥才能解密。

非对称加密算法实现机密信息的交换过程为:甲方生成“一对密钥”并将其中一个作为公钥向其他方公开;得到该公钥的乙方使用该密钥对机密信息进行加密后发送给甲方;甲方再用自己的另一个专用密钥对加密后的信息进行解密。
最有名的非对称加密算法当属 RSA 了。

非对称加密的核心是:拥有两把密钥。

简单描述就是:一把钥匙加密,另一把钥匙解密,加密的钥匙给别人加密,解密的钥匙自己拿着不给别人,这样的话别人负责加密,自己负责解密。

认证算法:RSA

RSA 密钥协商的过程并不复杂:

  1. 任意客户端对服务器发起请求,服务器首先发回复自己的公钥到客户端(公钥明文传输),私钥服务端自己保留且只有其自己知道;
  2. 客户端使用随机数算法,生成一个密钥 S(Random),使用收到的公钥进行加密并生成 C,把 C 发送到服务器;
  3. 服务器收到 C,使用公钥对应的私钥进行解密,得到密钥 S;
  4. 上述交换步骤后,客户端和服务器都得到了密钥 S,也称为预主密钥(pre-master);
  5. 双方都通过这个 密钥S 对明文进行加密和解密;

在DTLS中,服务器发送的“公钥”是通过 Certificate 报文发送的,而 C 是通过 Client Key Exchange 报文发送的。在WebRTC中,C 和 S 都提供证书的目的,是双方都需要用来验证指纹。

  • 公钥:

  • 密钥(公钥加密后):

密钥交换算法:DHE

DEH 密钥协商的过程:

  1. 客户端计算一个随机值 Xa,使用 Xa 作为指数,即计算 Pa = q^Xa mod p,其中 q 和 p 是全世界公认的一对值。客户端把 Pa 发送至服务器作为公钥,Xa 作为自己私钥,仅且自己知道;
  2. 服务器和客户端计算流程一样,生成一个随机值 Xb,使用 Xb 作为指数,计算 Pb = q^Xb mod p,将结果Pb 发送至客户端,Xb 仅自己保存;
  3. 客户端收到 Pb 后计算 Sa = Pb ^Xa mod p;服务器收到Pa后计算 Sb = Pa^Xb mod p;
  4. 算法保证了Sa = Sb = S,故密钥交换成功,S为密钥(预主密钥);

DTLS协议中,DHE参数 和 Pb 都是通过 Server Key Exchange发送给客户端,Pa 通过 Client Key Exchange 发送给服务器。Server Key Exchange 的结尾处需要使用服务器私钥对该报文本身进行签名,以表明自己拥有私钥。

密钥交换算法:ECDHE

  1. 客户端随机生成随机值 Ra,计算Pa(x, y) = Ra * Q(x, y),Q(x, y) 为全世界公认的某个椭圆曲线算法的基点,将 Pa(x, y) 发送至服务器;
  2. 服务器随机生成随机值 Rb,计算 Pb(x,y) = Rb * Q(x, y)。将 Pb(x, y) 发送至客户端;
  3. 客户端计算Sa(x, y) = Ra * Pb(x, y);服务器计算Sb(x, y) = Rb *Pa(x, y)
  4. 算法保证了Sa = Sb = S,提取其中的S的x向量作为密钥(预主密钥)

密钥协商

确定角色协商(a=setup:)

在 DTLS 协议,通信的双方有 Client 和 Server 之分。在 WebRTC 中 DTLS 协商的身份是在 SDP 中描述和确定的,描述如下:

  • setup:active:作为Client主动发起协商;
  • setup:passive:作为Server等待Client发起协商;
  • setup:actpass:作为Client主动发起协商,作为Server等待发起协商;

下面的截图,是当Web端在进行SDP握手后得到的 Answer:

在SDP交换之后,通信双方就确立了DTLS时谁是客户端,谁是服务端。

确定算法套件(Cipher Suite)

ClienHello 和 ServerHello 是用来协商 DTLS 的 Version、CipherSuites、Random 以及 Extensions 信息,这里,我们着重强调 CipherSuites:

客户端给出自己能支持的加密套件 Cipher Suites。服务端收到后选择自己能支持的回应一个,比如 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014),加密套件确定了:

  • 密钥交换算法:用于在握手期间协商会话密钥,常见的有 RSA、DHE、ECDHE 等;
  • 认证算法:用于身份验证,确保通信双方的身份合法,常见的有 RSA、ECDSA 等;
  • 加密算法:用于对数据进行加密,确保数据在传输过程中不会被窃取,常见的有 AES 等;
  • 哈希算法:用于计算校验和,以确保数据的完整性,常见的有 SHA-256、SHA-384 等;

例如下面这个套件,其代表的含义:

  • 秘钥交换算法:ECDHE
  • 认证算法:RSA
  • 加密算法:AES_256_CBC
  • 哈希算法:SHA

一种相对较老的套件,因为它仅使用RSA来进行密钥交换,没有交换算法,这在一些安全性场景下可能会存在一些弱点。现代的加密套件通常会使用 DHE、ECDHE 等更强大的密钥交换算法来提供更好的安全性。

  • 秘钥交换算法:无
  • 认证算法:RSA
  • 加密算法:AES_256_CBC
  • 哈希算法:SHA

交换随机数(Random)

双方的随机数,参与到生成一些重要数据:

主密钥(Master Secret)

交换的随机数以及每个端点的证书、密钥协商方式等信息将被用来生成主密钥。主密钥是一个对称密钥,它会被用来生成会话密钥。

会话密钥(Session Key)

主密钥会被用来派生一个或多个会话密钥。会话密钥是对称密钥,用于加密和解密通信数据。由于对称密钥的加密和解密速度较快,会话密钥会在通信过程中动态生成,从而提供更高的效率。

预主密钥(Per-Master Secret)

在一些密钥交换方式中,会使用一个预主密钥来进行进一步的派生,最终生成主密钥。这样做的目的是为了避免在通信过程中直接传输主密钥,提高安全性。

会话标识(Session Identifier)

会话标识是一个随机数,用于标识当前会话。它可以用于缓存会话信息,从而在未来的通信中重用会话密钥,提高效率。

MAC密钥

会话密钥还会派生出用于加密和生成消息认证码(MAC)的密钥。这些密钥将用于确保通信数据的机密性、完整性和认证;

总之,交换随机数后,通过握手过程中的派生步骤,生成了主密钥、会话密钥、预主密钥(某些情况下)、会话标识以及加密和MAC密钥等关键内容,用于确保通信的安全性和机密性。这些密钥和标识将在后续的通信中起到重要作用。

其他扩展(Extensions)

客户端给出自己要使用的扩展协议,服务端可以回应自己支持的,如果不回应则表示不支持。下面列出几个 WebRTC 用到的扩展:

  • use_srtp

DTLS 握手完成后(Finished)使用 SRTP 传输数据,DTLS 生成 SRTP 的密钥。ClientHello 中的扩展信息定义了 SRTP Protection Profiles 和 srtp_mki。

  • supported_groups

原来的名字为 elliptic_curves,描述支持的 ECC 加密算法。

  • signature_algorithms

DTLS 1.2 的扩展,指定使用的 Hash 和 Signature 算法:

身份验证(Certificate)

服务端通过 Hello 消息,协商交换“密钥的方法”后,将服务端的证书发送给客户端,用于客户端对服务端的身份进行校验。服务端发送的证书必须适用于协商的 KeyExchange 使用的加密套接字,以及 Hello 消息扩展中描述的 Hash/Signature 算法对。

在 WebRTC 中,通信的双方通常使用自签名证书。可问题是,怎么知道对端发来的证书是可信任的呢?

RFC4572 定义一种机制,通过在 SDP 中增加自签名证书的安全哈希,称为“证书指纹”,在保证 SDP 安全传输的前提下,如果提供的证书的指纹与 SDP 中的指纹匹配,则可以信任自签名证书。

a=fingerprint:sha-256 22:2A:62:B0:35:75:00:13:F0:27:2B:EC:CB:45:B5:B7:5D:97:E5:A7:A2:A9:92:F8:2B:9F:66:65:97:4C:B4:13

密钥交换(KeyExchange)

Server Key Exchange

用来将服务端使用的公钥,发送给客户端。分为两种情况:

  • RSA算法:假设服务端使用的是RSA算法,因为RSA算法使用的公钥已经在Certificate中描述,所以不需要重新生成公钥再发送了;
  • DH算法:根据对方的公钥和自己私钥计算共享密钥。因为客户端和服务端都只知道自己的私钥,和对方的公钥。而他们的私钥都不同,根据特殊的数学特性,他们能计算出同样的共享密钥;

Client Key Exchange

用来将客户端使用的公钥,发送给服务端:

  • RSA算法:如果密钥协商使用的是RSA算法,发送使用服务端RSA公钥,对 PremasterSecret 加密发送给服务端;

  • DH算法:如果密钥协商用的是DH算法,并且在证书中没有描述,那么,就需要在客户端使用的DH算法公钥发送给服务端,以便计算出共享密钥;

KeyExchange 的结果是,Client 和 Server 获取到了 RSA Key, 或通过 DH 算法计算出共享密钥。

证书验证(CertificateVerify)

客户端使用 ClientRequest 中描述的 Hash/Signature 算法,对收到和发送的 HandShake 消息签名发送给 服务端,服务端对签名进行校验。

加密验证(Finished)

当服务端和客户端完成对称密钥的交换后,通过 ChangeCipherSpec 通知对端进入加密阶段,epoch 加 1。

随后客户端使用交换的密钥,对 "client finished" 加密,使用 Finished 消息,发送给服务端。Server 使用交换的密钥,对 "server finished" 进行加密发送给客户端。一旦验证了 finished 消息后,就可以正常通信了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

毕加索解锁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值