我试图对 SSL/TLS 的工作原理有所了解,并查看了TLS 1.2 和 TLS 1.3 中的TLS 握手,以及来自服务器的随机数在哪里发挥作用。由于每个 TLS 请求都会在熵方面产生成本,因为需要派生加密密钥,我想知道为什么服务器不会很快耗尽熵。
首先,我查看了带有 RSA 密钥交换
的 TLS 1.2:根据TLS 1.2 标准第 6 节server random
,主密钥的派生源在非常情况下是32 字节长。我希望服务器从/dev/random
.
接下来,我查看了带有临时 Diffie-Hellman 密钥交换的 TLS 1.3:
客户端和服务器都生成自己的私有ECDHE 参数集。之后他们做了他们的 Diffie-Hellman 的事情并获得了一个共享的秘密。此共享密钥用于派生用于加密的对称密钥和用于计算 HMAC 以检查消息完整性的密钥。因此,我假设我的加密质量取决于 ECDHE 参数的质量。如果我使用曲线 NIST P-256,那么根据这个答案,我至少需要一个 128 位的种子。
总结:
在我的 TLS 1.2 示例中,服务器需要生成 256 位的熵,而在 1.3 示例中,服务器需要生成 128 位的熵。我假设必要的位取自/dev/random
. 与单次 TLS 握手所需的位数相比4096
,返回的熵池的最大大小似乎非常小。cat /proc/sys/kernel/random/poolsize
除非我的计算不正确,否则假设熵池没有快速重新填充,我将完全耗尽我的熵池,只有 16 个 TLS 1.2 请求。
问题:
- 如果我的服务器收到大量 TLS 请求,它会耗尽熵吗?或者它是否可以从 TLS 请求中以某种方式补充熵池,可能是通过使用数据包来回传输的时间或类似的东西。
- 假设我想保存一些熵。与 TLS 1.2 相比,具有 256 位 ECC 的 TLS 1.3 在熵方面的成本会更低吗?在上面的示例中,我发现 TLS 1.2 的熵成本为 256 位,而 TLS 1.3 仅为 128 位。
Client Hello
如果有人在没有建立真正连接的情况下发送大量消息,他会以这种方式耗尽我的熵池吗?我会假设单个Client Hello
在熵方面并没有给我太多,但会给服务器带来很大的负担,因为它需要用Server Hello
包含 TLS 1.2 中的 32 字节随机数据的 a 来回答。
不。阻塞是用于当系统存在完全零熵的风险时。也许在第一次启动时生成 ssh 主机密钥。在正常操作期间不适用于 TLS,导致拒绝服务毫无意义,因为它缺乏随机位。
使用(非阻塞)密码安全的伪随机数生成器。如果您希望使用内核源代码,请考虑在 Linux 上使用 getrandom() 或 /dev/urandom,或在 Windows 上考虑 BCryptGenRandom。它们使用使 TLS 和其他算法工作的相同加密原语;如果他们不能从一个小种子中生成大量明显随机的比特,那么加密就会被破坏。
尽管 TLS 库可能会使用自己的 CSPRNG,但内核源代码中只有一个小种子。简单地将协议中的随机位相加并不表示从系统熵池中读取了多少。
关于操作系统,请务必说明您使用的发行版。Linux 积极阻止 /dev/random 是非典型的。大多数 BSD 以与 /dev/urandom 相同的方式处理它。
简短的回答:使用 /dev/urandom。在 Linux 上需要阻止 /dev/random 的可怕之处在于迷信。对数十 TB 随机位的分析表明它们是相同的。