9

我正在编写一个应用程序,用户可以在其中通过端到端加密在设备之间进行通信。为此,我使用 libsodium 加密库。非对称加密函数 crypto_box(...) 需要一个随机数作为参数之一。

我对如何处理随机数有点困惑。发给一个人的每条消息都需要使用不同的随机数加密吗?这似乎不正确,因为我必须将使用过的随机数存储在具有公共访问权限的服务器上,攻击者可以再次使用其中一个使用过的随机数。

从 A 发送到 B 的所有消息都具有不同的 nonce 就足够了吗?

有人可以向我解释一下吗。

4

2 回答 2

6

发给一个人的每条消息都需要使用不同的随机数加密吗?

是的。事实上,对于同一个私钥,永远不会使用超过一个的同一个随机确实,您必须跟踪 nonce 才能完成此操作。

这似乎不正确,因为我必须将使用过的随机数存储在具有公共访问权限的服务器上,攻击者可以再次使用其中一个使用过的随机数。

为什么必须将 nonce 存储在具有公共访问权限的服务器上?您认为攻击者如何“使用”随机数?他们需要你的私钥才能这样做。

为什么不能将 nonce 存储在与私钥相同的位置?

于 2014-06-12T20:51:03.513 回答
6

使用给定的共享密钥发送的每条消息都需要唯一的随机数。随机数不必是秘密的;一个简单的计数器完全可以;即使相同的消息被发送两次,更改随机数中的单个位也会使密文看起来完全不同。

什么是共享秘密?它是根据(A 的密钥,B 的公钥)或(A 的公钥,B 的密钥)计算得出的密钥。A 和 B 根据他们拥有的内容执行不同的计算,但最终得到相同的共享密钥。

中使用的共享密钥crypto_box长度为 256 位。这是巨大的。您可以放心地认为,每个“对话”的共享秘密都是独一无二的。

因此,(A, B)、(A, C) 和 (C, B) 可以使用相同的随机数安全地交换消息。但是如果 A 使用给定的 nonce 向 B 发送消息,则 B 不能使用相同的 nonce 向 A 发送消息。对于 A 和 B 之间的对话期间交换的所有内容,Nonce 必须是唯一的。

所以,一个简单的计数器就可以了。让 A 选择偶数,将奇数留给 B,在发送每条消息后将随机数增加 2,然后你就可以开始了。

但是crypto_box构造中使用的密码实际上有一个非常大的随机数。192 位。

这意味着,如果您忽略我写的所有内容,并且每次发送消息时都随机选择一个随机数,那么发生冲突的可能性非常小,您可以放心,它在实践中永远不会发生。

Sodium 中包含的一些流密码(AES128-CTR、ChaCha20、Salsa20)具有更短的随机数,并且需要计数器以避免冲突。这就是为什么它们位于文档的“高级”部分。

但是使用crypto_boxand crypto_secretbox,每次只需随机选择一个随机数 ( randombytes_buf(nonce, sizeof nonce)),你就会安全。

于 2015-06-10T22:50:35.037 回答