根据 RFC 5246,TLS 中的 nonce 是无用的(就安全性而言),如果是,为什么它们不只是随机数据?

信息安全 tls 随机数
2021-09-03 13:35:35

我知道随机数在安全性中的常见用法(在本主题中有很好的描述)。然而,在检查 SSL/TLS 协议时,我们可以注意到,根据RFC,随机数以明文形式发送,ClientHello.random并且ServerHello.random很容易被攻击者重放。那么为什么它们还在 TLS1.2 中使用呢?他们只是为了区分另一个用户吗?他们实际上没有与他们一起进行的挑战。

我在这里提到 SSL/TLS (TLS1.2) 的特定情况,并且想知道在这种情况下,它们的 nonce 的使用是否会对协议的任何步骤的安全性产生影响如果没有,为什么要引入它?

这个问题的公认答案描述了为什么在使用 TLS/SSL 的特定情况时不需要随机数,因为在通道上使用了强身份验证,那么它们在协议中实际上是无用的吗?

编辑 :

  1. 随机数(date + alea)以明文形式发送,因此我们可以将它们视为用户的公共数据,因为任何攻击者都可以通过监听客户端和服务器之间的交换来获取它们。

  2. 考虑到 1) 以及 RFC 没有规定如果我们必须在协议的任何步骤检查 nonce 的事实,重放攻击仍然是可能的。

因此,如果这些数据是“公开的”,我们为什么要把这些数据作为安全参数呢?如果它们不是安全参数,是否有仅限于客户端/服务器标识符的用途?

3个回答

随机数不需要保密。nonce 的优点是只出现一次,不会为外人所知。客户端随机数和服务器随机数以明文形式发送的事实并不能阻止它们成为“随机数”。

实际的“nonce”是客户端和服务器随机的串联这在几个地方是明确的,特别是在RFC 5246 的第 6.3 节中,它处理密钥计算:用于加密的对称密钥和应用程序数据的 MAC 来自“主密钥”和两个随机数的连接:

  key_block = PRF(SecurityParameters.master_secret,
                  "key expansion",
                  SecurityParameters.server_random +
                  SecurityParameters.client_random);

这两个随机值也将出现在CertificateVerifyFinished消息的计算中,因为它们都使用对所有先前握手消息计算的哈希值,其中包括两个“hello”消息和它们包含的随机值。

所以客户端随机通过发送一个新的来保护自己client_random:无论在线上发生什么,客户端都会使用它发送的随机值进行密钥计算。同样,服务器使用其server_random. 要了解保护如何工作,请考虑重放攻击:攻击者观察到客户端和服务器之间的握手,然后希望与服务器重放相同的握手,从而冒充客户端。攻击者观察到这一点:

ClientHello (ch1)            --->
                             <---        ServerHello (sh1)
                                         Certificate (c1)
                                         ServerHelloDone (shd1)
ClientKeyExchange (cke1)     --->
ChangeCipherSpec
Finished (cf1)
                             <---        ChangeCipherSpec
                                         Finished (sf1)

然后攻击者连接到服务器,并发送ClientHello(ch1)的精确副本。然而,服务器以不同 ServerHello的响应(我们称之为 sh2):这ServerHello与之前使用的(sh1)非常相似,但具有一个新server_random值。然后攻击者可以继续握手,但是当攻击者发送Finished消息 cf1 时事情就会崩溃:该消息应该包含从所有先前的握手消息派生的散列,并使用从主密钥派生的密钥进行加密(攻击者这样做不知道,他只是“重播”)以及来自客户端和服务器的随机数。对于这两种计算,服务器都期望Finished加密的内容和密钥是使用随机来自ClientHello和来自它自己的ServerHello(即这里的“sh2”消息)。“cf1”消息将不匹配,因为它是使用来自初始握手的哈希和密钥计算的,来自 ch1 和 sh1 的随机数,而不是 sh2。

记录的数据包不能被攻击者全部重放,因为根据定义,攻击者只重放了一半的对话。当攻击者试图冒充客户端时,他可以代表客户端发送所有数据包,但必须使用真正的服务器响应(如果攻击者同时冒充客户端和服务器,那么他可以进行“完美重放”,但他实际上只是在自言自语,所以这被认为是一种精神疾病,而不是攻击)。server_random从而强制执行阻止重放攻击的分歧

(类似的情况是攻击者在与真正的客户端交谈时试图冒充服务器:client_random保护客户端免受重放攻击。)

替代描述:客户端和服务器实际上确实验证了随机数。他们在计算对称密钥并检查接收到的Finished消息的内容时会隐式执行此操作。客户端不会满足于Finished从服务器接收到的消息,除非该消息是计算出来的,然后使用客户端刚刚发送的(以及其他值)加密client_random,而不是其他值(对于服务器也是如此)。

客户端和服务器“随机”实际上不一定是随机的,尽管它是可取的。如上所述,客户端和服务器随机值中的实际值是它们与以前的值不同,对于每次握手。它们是公共价值观,如果它们是可预测的,就不会有任何严重的问题事实上,即使攻击者可以预测给定客户端和服务器将使用的client_random和/或的确切值server_random,这也无助于他进行重放攻击:要成功重放握手,攻击者不能简单地知道客户端和服务器随机;他必须安排客户端和服务器重复使用与之前重播的握手相同的随机数。由于攻击者一次只能模拟一个,因此他无法强制重复使用。

您可能会注意到,上述 32 字节随机数实际上以 4 个非随机字节开始:这些字节编码当前日期和时间(自传统时刻以来的秒数)。这些字节的目的是尝试确保这种不重用策略,即使对于 PRNG 功能异常严重以至于它们重用以前的随机值的实现也是如此。但是,如果客户端没有好的随机源,这可能会影响ClientKeyExchange主密钥和主密钥的安全性,尤其是基于 RSA 的密钥交换(这是司空见惯的)。

它可以防止重放攻击。 考虑一个攻击者正在记录客户端和服务器之间的所有通信的场景。之后,攻击者重新连接到服务器并将所有记录的消息发送回服务器。TLS 通过使用连接唯一的 nonce 或 connection-id 来防止这种攻击。攻击者无法提前预测nonce,因为nonce是使用一些随机事件生成的,例如日期、时间等,因此攻击者无法正确响应服务器请求。如果攻击者拥有高端系统,那么他可以记录客户端和服务器之间的许多会话。之后,攻击者可以尝试根据服务器在 SERVER_Hello 消息中发送的 nonce 来选择正确的会话。TLS 协议使用至少 128 位随机数,最大长度为 224 位,因此攻击者需要记录 2^64 或 2^112 个 nonce 才能有 50% 的机会选择正确的会话。很难有记录 2^64 或 2^112 消息的设备。

它可以防止重放攻击

握手的第4步和第5步的方式如下

4. c --> s: <AUTHc>
5. s --> c: <AUTHs>

c is the client
s is the server
<> means encryption using the record protocol with the shared key (Kcs) between c and s
AUTHc is a token in the form of prf(Kcs, **transcript of messages 1,2**)
AUTHs is a token in the form of prf(Kcs, **transcript of messages 1,2,3**)

prf is a pseudorandom function with the key and a transcript of certain messages as input.
The transcript is essentially a hash of a certain number of messages.

随机数在消息 1 和 2 中并包含在这些令牌中,因此避免了重放攻击。