【问题标题】:Using AES as a portable RNG with a truly random seed?使用 AES 作为具有真正随机种子的便携式 RNG?
【发布时间】: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


【解决方案1】:

我认为这样做充其量只是一个 hack。

AES 是一种加密算法,而不是随机数生成算法。我不希望一遍又一遍地应用 AES 来产生不错的随机性。

您提到您担心性能并希望使用 AES 硬件。 AES 硬件加速的原因是 AES 相当复杂。然而,大多数 PRNG 不是;例如,xorshift 只是几个 xor 和 shift 操作。您还需要依赖具有 AES 加速器的目标硬件。

从某个地方(不难找到)获取一个不错的 C PRNG 库,用您的共享随机数播种它,然后将其保留。

【讨论】:

  • I wouldn't expect applying AES over and over again to produce decent randomness. 好吧,AES(++k) 被测试为相当不错的 RNG,IIRC。尽管获得合理 PRNG 库的建议是物有所值的。
【解决方案2】:

您应该阅读以下内容,其中包含指向 PRNG 上其他参考资料的链接

http://c-faq.com/lib/rand.html

不要做你正在做的事情,除非你在同行评议的文献中找到了可行的方法,即使那样我也会谨慎对待它。如果你想要一个便携式 PRNG,那么上面链接中给出的就是

#define a 48271
#define m 2147483647
#define q (m / a)
#define r (m % a)

static long int seed = 1;

long int PMrand()
{
    long int hi = seed / q;
    long int lo = seed % q;
    long int test = a * lo - r * hi;
    if(test > 0)
        seed = test;
    else    seed = test + m;
    return seed;
}

请注意文档底部附近对a 的更改。你也不应该相信我刚刚写的任何东西,即做你的功课,并确保上述或其他一些 PRNG 适用于你的应用程序。

【讨论】:

  • en.wikipedia.org/wiki/… 根据这篇文章,我的建议似乎很普遍。性能似乎是唯一的批评。
  • @Ermir A CPRNG 不是您在问题中所描述的。随机数和安全性可能经常一起出现,但它们是两个截然不同的主题。
【解决方案3】:

您没有说明您的安全要求。如果您想要一个加密安全的解决方案,那么您的问题并非微不足道。请参阅A Block Cipher based Pseudo Random Number Generator Secure Against Side-Channel Key Recovery 了解一种可能的解决方案。

由于安全要求,这样的 RNG 会很慢。正如三十二上校所说,您的问题可能会通过非加密 RNG 更好地解决,它会更快并且可能更易于维护。

【讨论】:

    猜你喜欢
    • 2021-10-28
    • 2020-04-25
    • 2020-12-15
    • 2022-07-11
    • 2017-05-31
    • 1970-01-01
    • 1970-01-01
    • 2015-05-10
    • 2011-02-09
    相关资源
    最近更新 更多