SecureRandom的行为

cha*_*uru 8 java security random algorithm cryptography

尽管在阅读了很多文章后SecureRandom,我对使用SecureRandomJava中的Security API 感到疑惑.在下面的例子中.

public class SecureRandomNumber {
public static void main(String[] args) throws NoSuchAlgorithmException {

    TreeSet<Integer> secure = new TreeSet<Integer>();
    TreeSet<Integer> unSecure = new TreeSet<Integer>();
    SecureRandom sr = new SecureRandom();
    byte[] sbuf = sr.generateSeed(8);
    ByteBuffer bb = ByteBuffer.wrap(sbuf);
    long d = bb.getLong();
    sr.setSeed(d);

    Random r = new Random();
    r.setSeed(System.nanoTime());
    for (int k = 0; k < 99999; k++) {
        int i = sr.nextInt();
        if (!secure.add(i)) {
            System.out.println("Repeated Secure Random Number");
        } else {
//              System.out.println("************Unique***********");
        }
        int j = r.nextInt();

        if (!unSecure.add(j)) {
            System.out.println("Repeated UnSecure Random Number");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

}

当我运行这个程序时,我没有发现使用a的任何额外好处,SecureRandom因为它几乎给出了相同的结果.

如果我在这里做正确的事情,谁能让我知道?

emb*_*oss 17

一般来说,你是对随机数的常见误解的牺牲品:随机序列并不意味着数字不能在该序列中重复.恰恰相反,它具有很高的概率.这种误解实际上用于说明人类从真实的序列中产生的"随机"序列.人类生成的0和1的"随机"序列可能如下所示:

0,1,0,1,1,0,1,0,0,1,0,1,0 ......

虽然一个真正的随机序列并不害羞重复相同的数字超过两次:)一个很好的例子是统计测试也寻找重复.

两种发电机都具有良好的"统计特性"

加密地保护随机数会以某种方式产生"更多随机"值也是一种常见的误解.他们的统计概率可能非常相似,并且在这些标准统计测试中都表现得非常好.

哪里用哪个

因此,无论您选择的是PRNG还是加密安全的PRNG(CSPRNG),它实际上取决于您想要做什么."正常"PRNG完全可以用于模拟目的,例如蒙特卡罗方法等.CSPRNG的额外好处将使您具有不可预测性.因为CSPRNG可以"做得更多"的机会很高,其性能也会比香草PRNG的性能更差.

可以证明,"安全"PRNG的概念与预测其输出的下一位的能力紧密耦合.对于CSPRNG,在任何时候预测其输出的下一位在计算上是不可行的.只有当你将其种子价值视为秘密时,这才有效.一旦有人发现了种子,整个事情就变得容易预测 - 只需重新计算CSPRNG算法已经生成的值,然后计算下一个值.可以进一步证明,对"下一位预测"免疫实际上意味着没有任何统计测试可以区分CSPRNG的分布与真实随机均匀分布的分布.因此PRNG和CSPRNG之间存在另一个区别:虽然良好的PRNG在许多统计测试中表现良好,但CSPRNG保证在所有测试中表现良好.

经验法则在哪里使用哪个

  • 你在一个"敌对"环境中使用CSPRNG,你不希望外部能够猜出敏感信息(会话ID,在线扑克赢得/丢失真钱),....
  • PRNG处于一个仁慈的环境中,你只需要良好的统计属性但不关心可预测性(蒙特卡罗模拟,单人扑克与电脑,一般电脑游戏) - 即没有钱可以赢或者生活将是如果有人能够成功地预测这些随机数,那就输了.


Dav*_*rtz 5

安全和不安全的算法通常会给出几乎相同的结果.您无法检测输出中的安全漏洞.一扇带有不可拆卸锁的门和一把带锁的门可以琐碎地采摘,看起来几乎一样,如果你只是转动手柄也不会打开.这是编写安全代码和处理加密和身份验证之类的事情的原因之一,这是使用专门的设计,开发,特别是测试技术进行编程的一个领域.