【问题标题】:PRNG seeded by key in java在java中按键播种的PRNG
【发布时间】:2013-04-15 13:38:46
【问题描述】:

我需要使用一个键来伪随机地创建数字。 key 是一个转换为字节数组的字符串。 这就是我想出的:

    int N=10;
    int key[]= {13,10,1,5};
    int tmp,j=0;
    for (int i=0; i < N; i++) { 
        j = (j + key[i % key.length]) % N; 
        System.out.println(j);
    }

此代码取自 RC4 的 PRNG 并进行了修改。它没有按预期工作,值重复。

【问题讨论】:

  • 问题是什么?
  • 以上代码不会随机生成 0 到 10 的数字。我以为这是暗示。 :)
  • 如何判断输出不是随机的?
  • RC4 修改背后的原因是什么?为什么不使用new SecureRandom(myByteArray)?注意,SecureRandom 支持RC4 & ARCFOUR
  • 我可以使用securerandom随机生成一个范围内的所有数字吗?

标签: java random cryptography prng random-seed


【解决方案1】:

此代码将为您提供数字 0 到 9 的一致、随机排列...排列是随机的,但使用相同的键将始终相同

public static void main(String[] args) throws Exception
{
    byte key[]= {13,2,4,6,7}; 
    SecureRandom random = new SecureRandom(key); 

    List<Integer> nums = new ArrayList<Integer>();
    for (int i = 0; i < 10; i++) { 
        nums.add(i);
    }

    Collections.shuffle(nums,random);

    for(Integer n: nums) {
        System.out.println(n);
    }
}

【讨论】:

    【解决方案2】:

    嗯,第一个问题是你试图从一个四字节的密钥中创建一个 PRG。这本质上是不安全的。攻击者将能够很容易地猜测。

    第二个问题是你只使用了十轮 PRG,这意味着即使你有一个 128 位的密钥,你也只会使用前 10 轮,这本质上是不安全的。

    您的第三个问题是您使用 i % key.length 作为 mod 函数的索引。这是一个问题,因为您使用的索引将恰好递增一。如果你有一个更大的密钥,这将更好地模拟随机性,但由于你的密钥只有四个字节,它不会。

    此外,您似乎在函数末尾任意添加了% N。我不确定你想要完成什么,但我并不惊讶你会发现重复的模式。您已将函数压缩为一个很小的数字。同样重要的是要注意,随着迭代次数的增加,输出大小也会增加,这通常是没有用的。

    你的算法也忽略了RC4生成算法的大部分关键点;阅读here 了解更多信息。

    没有办法告诉你如何解决这个问题,因为我认为你可以解决这个问题。我认为这个概念本质上是不安全的。

    【讨论】:

    • 我需要的是随机生成最多 N 的数字。然后可以将其用作 int 数组的可逆洗牌的索引。
    • 对,但你问的不是这个。
    • 嗯,我需要的是那个。你能告诉我怎么做吗?
    • 使用Java的SecureRandom(mByteArray)
    • 如何使用 SecureRandom 生成一个范围内的数字而不重复?
    猜你喜欢
    • 2015-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-03
    • 1970-01-01
    • 2020-11-21
    相关资源
    最近更新 更多