生成随机数 C++

Generate nonce c++

我想知道是否有办法使用 OpenSSL 或 Crypto++ 库生成 Cryptographic Nonce。除了使用自动播种池生成一组随机字节之外,还有什么比它更重要的吗?

每个随机数都需要一个唯一的数字。您可以使用序列号或随机数。为了帮助确保唯一性,虽然不是必需的,但通常会向随机数添加时间戳。要么将时间戳作为单独的字段传递,要么将其与 nonce 连接起来。有时还会添加 IP 地址和进程 ID 等信息。

当您使用序列号时,您无需担心跳号。没关系。只要确保你永远不会重复。它在您的软件重新启动时必须是唯一的。这是添加时间戳可以提供帮助的地方。因为以毫秒为单位的时间+序列号几乎可以肯定在服务器重新启动时是唯一的。

对于伪随机数生成器,任何人都应该没问题。只要确保您使用足够大的 space 就不可能有效地获得重复项。同样,增加时间会降低重复的可能性,因为您需要在同一毫秒内两次获得相同的随机数。

您可能希望对 nonce 进行哈希处理以隐藏其中的数据(例如:进程 ID),尽管只有在 nonce 中包含安全随机数时哈希才是安全的。否则,随机数的查看者可能会猜测组件并通过重做哈希进行验证(即:他们猜测时间并尝试所有可能的过程 ID)。

没有。如果 nonce 足够大,那么自动播种 DRBG(确定性随机位生成器 - NIST 命名法)就可以了。我建议使用大约 12 个字节的随机数。如果随机数需要 16 个字节,那么您可以将最低有效位(通常是最右边的字节)设置为零以实现最大兼容性。

只使用 API 提供的加密安全随机数生成器应该没问题 - 它们应该使用从操作系统(可能还有其他数据)获得的信息来播种。 添加 系统时间到种子数据绝对没有坏处。

或者,您可以使用序列号,但这需要您保持某种状态,这可能很难跨调用。请注意,有许多陷阱可能会让时钟重复自身(夏令时、OS 变化、电池没电等)。

仔细检查随机数生成器是否不会重复生成足够大的输出永远不会有坏处。仅存在编程或系统配置错误的问题,例如当对 Debian 进行静态代码分析后修复导致 OpenSSL RNG 根本无法播种时 .

I am wondering if there is a way to generate a cryptographic nonce using OpenSSL or Crypto++ libraries.

加密++:

SecByteBlock nonce(16);
AutoSeededRandomPool prng;

prng.GenerateBlock(nonce, nonce.size());

OpenSSL:

unsigned char nonce[16];
int rc = RAND_bytes(nonce, sizeof(nonce));
unsigned long err = ERR_get_error();

if(rc != 1) {
    /* RAND_bytes failed */
    /* `err` is valid    */
}

/* OK to proceed */

Is there anything more to it than just generating a set of random bytes using autoseeded pools?

随机数基本上是一个 IV。它通常被认为是一个 public 参数,如 IV 或 Salt。

随机数在安全上下文中必须是唯一的。你可能也需要一个不可预测的随机数。

独特性和不可预测性是两个不同的属性。例如,从 0000000000000000 开始的计数器是唯一的,但它也是可预测的。

当你同时需要唯一性和不可预测性时,你可以将随机数划分为一个随机值和一个计数器。随机值将占用 16 字节随机数中的 8 个字节;而计数器将占用 16 字节随机数的剩余 8 字节。然后你使用一个增量函数基本上每次你需要一个值时执行i++

您不需要 8-8 拆分。 12-4 和 4-12 一样有效。这取决于应用程序和重新加密前所需的随机数。重新加密通常由纯文本字节数驱动。

16-0 也有效。在本例中,您使用的是随机值,避免了计数器,也避免了增量函数。 (增量函数基本上是级联加)。

NIST SP800-38C and SP800-38D 提供了几种创建随机数的方法,因为 CCM 和 GCM 使用它们。

另见 Crypto Stack Exchange 上的 What are the requirements of a nonce?