我想知道是否有办法使用OpenSSL或Crypto ++库生成Cryptographic Nonce。还有什么比使用autoseeded池生成一组随机字节更多吗?
答案 0 :(得分:5)
我想知道是否有办法使用OpenSSL或Crypto ++库生成加密nonce。
<强> 加密++ 强>:
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 */
除了使用autoseeded池生成一组随机字节之外,还有什么呢?
nonce基本上是IV。它通常被认为是一个公共参数,如IV或Salt。
nonce在安全上下文中必须是唯一的。您可能还需要一个nonce不可预测。
独特性和不可预测性是两个不同的属性。例如,从0000000000000000
开始的计数器是唯一的,但它也是可预测的。
当您需要唯一性和不可预测性时,可以将随机数分为随机值和计数器。随机值将占用16字节随机数的8个字节;而计数器将占用16字节随机数的剩余8个字节。然后使用递增函数在每次需要值时基本执行i++
。
你不需要8-8分裂。 12-4工作,4-12工作。这取决于应用程序和重新加密前所需的随机数。重新加密通常由纯文本字节计数驱动。
16-0也有效。在这种情况下,您使用随机值,避开计数器,并避免增量功能。 (增量函数基本上是级联添加)。NIST SP800-38C和SP800-38D提供了几种创建nonce的方法,因为CCM和GCM使用它们。
另请参阅加密堆栈交换中的What are the requirements of a nonce?。
答案 1 :(得分:2)
每个随机数需要一个唯一的编号。您可以使用序列号或随机数。为了帮助确保唯一性,通常(尽管不是必需的)向nonce添加时间戳。将时间戳作为单独的字段传递或将其与nonce连接。有时也会添加IP地址和进程ID等信息。
使用序列号时,您不必担心跳过号码。没关系。只要确保你永远不会重复。在重新启动软件时,它必须是唯一的。这是添加时间戳可以提供帮助的地方。因为time-in-millis + serial-number在重新启动服务器时几乎肯定是唯一的。
对于伪随机数生成器,任何人都应该没问题。只要确保你使用足够大的空间,就有可能无法获得复制品。同样,添加时间会降低重复的可能性,因为您需要在同一毫秒内两次获得相同的随机数。
您可能希望对nonce进行散列以隐藏其中的数据(例如:进程ID),但如果在nonce中包含安全随机数,则散列只会是安全的。否则,nonce的查看者可能猜测组件并通过重做哈希来验证(即:他们猜测时间并尝试所有可能的proc ID)。
答案 2 :(得分:2)
没有。如果nonce足够大,那么自动DRBG(确定性随机位发生器 - NIST命名法)就可以了。我建议一个大约12个字节的随机数。如果nonce需要是16个字节,那么你可以将最低有效位 - 通常是最右边的字节 - 设置为零以获得最大的兼容性。
使用API提供的加密安全随机数生成器应该没问题 - 它们应该使用从操作系统获得的信息(可能还有其他数据)进行播种。为了确保将系统时间添加到种子数据中,它永远不会受到伤害。
或者您可以使用序列号,但这需要您保留某种状态,这种状态在调用时可能很难。请注意,有许多陷阱可能允许时钟重复(夏令时,操作系统更改,电池耗尽等)。
仔细检查随机数生成器是否重复输出足够大的内容永远不会受到伤害。编程或系统配置错误只会出现问题,例如:当Debian的静态代码分析后修复导致OpenSSL RNG不能播种时。