【发布时间】:2016-08-25 07:21:18
【问题描述】:
我正在编写一个服务,其中需要跨不共享代码库的多个平台(可能 C 除外)的确定性 RNG。随机数需要正好是 128 位长。给定一个预先协商的真正随机数,如果我使用 AES 生成随机数序列可以吗?它的工作原理是我会加密种子以获得第一个随机数,加密第一个随机数以获得第二个,等等。
基本上:
rand[0] = truly_random_number;
rand[1] = AES(truly_random_number);
rand[2] = AES(AES(truly_random_number));
rand[n] = AES(AES(AES...AES(truly_random_number...))) //n times
这里的一个参数 AES 被定义为明文总是全为零。
客户端将在通信时共享它们的序列号,因此它们中的任何一个都应该可以确定性地重建所需的结果。
这是对 AES 的正确使用吗?我可以为此使用更快的东西,比如 SHA-256 并截断结果吗?我应该只找到一些 RNG 的 C 实现并使用它吗?我倾向于 AES,因为我的目标平台有 AES 加速器,所以速度应该不是什么大问题。
【问题讨论】:
-
不保证所有客户端的 PRNG 都是相同的。为了确保我有这样的 PRNG,我必须在 C 中找到并实现一个好的 PRNG。至于仅使用上面一个参数的 AES,假设该参数始终为 0,或者只是一个给定的常数。
-
你也可以
rand[0] = AES(truly_random_number, 0); rand[1] = AES(truly_random_number, 1);等 -
如果你想问这个方案是否是一个安全的种子 CSPRNG,那么Cryptography 比 Stack Overflow 更适合。
-
1. NIST SP 800-90 已经使用 AES 定义了一个好的 DRBG (prng)。 2. 使用类似上述重复加密的方法可能会出现短周期问题(如果 rand[i] == rand[j] 则可以预测 rand[j+1] 将等于 rand[i+1])。 3. SHA256 在这个用途上并不比 AES 快。 4. 自然,你的对抗优势会在生日界限之后爆发,多亏了上面的第 2 条,这是一个可利用的优势。
-
假设您只是在做一些 Monte-Carlo 模拟(no 安全保证):Mersenne twister 在大量语言中非常常见,因此您几乎可以肯定找到针对您选择的语言进行了优化的实现。您可以执行验证步骤并从固定种子生成 n 个“随机”数字,并将其与已知输出进行比较,以确保它不会从您的下方改变。或者,重复的哈希(MD5、SHA512)最终可能比加密更快。
标签: c encryption random cryptography