【问题标题】:Will this algorithm generate a cryptographically-secure bitstream?该算法会生成加密安全的比特流吗?
【发布时间】:2011-05-23 05:45:05
【问题描述】:

我正处于创建黑桃游戏的艰难阶段,我很难想出一种加密安全的洗牌方式。到目前为止,我有这个:

  • 在调用 Random 之前获取 32 位系统时间
  • 从 Random 中获取 32 位
  • 调用 Random 后获取 32 位系统时间
  • 将系统时间按位相乘并将两半相异或
  • 将 Random 中的 32 位与第一个 xor 中的值进行异或,并将其称为种子
  • 使用种子创建一个新的随机数

基本上从这里我都保存了每个 Random 实例的 32 位结果,并用它来为下一个实例播种,直到我得到我想要的熵量。从这里我创建了一个交替步骤生成器来生成最终的 48 位种子值,用于我的最终 Random 实例来洗牌。

我的问题与交替步生成器之前的部分有关,但如果不是,因为无论如何我都会使用 CSPRNG,这个算法是否足够好?

或者,最终的 Random 实例是绝对必要的吗?我可以一次从 ASG 上抓取 6 位并取 mod 52 的值吗?

【问题讨论】:

  • 不是答案,但如果您需要 Java 中的加密安全 PRNG,请使用 SecureRandom。它很容易获得,很少需要任何配置——我知道的大多数 JRE 都提供了开箱即用的 SHA1PRNG 算法。
  • 从加密 PRNG 中获取尽可能多的内容。不需要做这么复杂的事情。
  • 按位乘法是什么意思?按位与?
  • 这个问题听起来更像是收集熵而不是洗牌。为什么不直接使用 /dev/urandom 作为加密安全 PRNG 的输入?

标签: java cryptography


【解决方案1】:

不,它可能对您的目的足够安全,但它肯定不是加密安全的。在快速系统上,您可能有两个相同的系统时间。最重要的是,乘法只会消除熵。

如果您不想这样做,您可以下载 RNG 的 FIPS 测试并使用您的 RNG 输入大量数据,然后对其进行测试。请注意,即使我在实际阅读有关 RNG 测试的文档时也遇到了麻烦,所以请准备好做一些数学运算。

所有这一切,而 Java 平台已经包含一个安全的 PRNG(它基于 SHA1 并使用操作系统的 RNG 作为种子)。操作系统几乎可以肯定会使用一些基于时间的信息作为种子,无需自己输入(当然,如果您真的愿意,您可以随时设置系统时间的种子)。

【讨论】:

    【解决方案2】:

    有时简单的答案是最好的:

    List<Card> deck; // Get this from whereever.
    SecureRandom rnd = new SecureRandom();
    java.util.Collections.shuffle(deck, rnd);
    // deck is now securely shuffled!
    

    【讨论】:

      【解决方案3】:

      您需要一种良好的洗牌算法和一种收集足够熵的方法来喂它​​,以便理论上它可以涵盖一副纸牌的所有可能排列。请参阅这个较早的问题:Commercial-grade randomization for Poker game

      【讨论】:

        猜你喜欢
        • 2016-05-28
        • 2017-08-11
        • 2013-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-07
        • 1970-01-01
        相关资源
        最近更新 更多