Java 安全随机行为

Java 安全随机行为,java,algorithm,security,random,cryptography,Java,Algorithm,Security,Random,Cryptography,尽管在阅读了许多关于SecureRandom的文章之后,我还是对SecureRandom安全API在Java中的使用遇到了疑问。在下面的例子中 public class SecureRandomNumber { public static void main(String[] args) throws NoSuchAlgorithmException { TreeSet<Integer> secure = new TreeSet<Integer>();

尽管在阅读了许多关于
SecureRandom
的文章之后,我还是对
SecureRandom
安全API在Java中的使用遇到了疑问。在下面的例子中

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");
        }
    }
}
公共类安全随机数{
公共静态void main(字符串[]args)抛出NoSuchAlgorithmException{
TreeSet secure=新的TreeSet();
TreeSet unSecure=新的TreeSet();
SecureRandom sr=新的SecureRandom();
字节[]sbuf=sr.generateSeed(8);
ByteBuffer bb=ByteBuffer.wrap(sbuf);
long d=bb.getLong();
高级固定种子(d);
随机r=新随机();
r、 设置种子(System.nanoTime());
对于(int k=0;k<99999;k++){
int i=sr.nextInt();
如果(!secure.add(i)){
System.out.println(“重复安全随机数”);
}否则{
//System.out.println(“***************唯一的*************”);
}
int j=r.nextInt();
如果(!不安全。添加(j)){
System.out.println(“重复不安全随机数”);
}
}
}
}

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


有人能告诉我我在这里做的事情是否正确吗

安全算法和不安全算法通常会给出几乎相同的结果。您无法检测输出中的安全缺陷。一扇门有一把不可撬开的锁,一扇门有一把可以随便撬开的锁,这两扇门看起来几乎一样,只要转动把手,两扇门都不会打开。这就是为什么编写安全代码和处理加密和身份验证等事情是使用专门技术进行设计、开发和测试的编程领域的原因之一。

SecureRandom不能确保每次都有唯一的随机数。它只是确保给定前面的数字,您无法预测下一个随机数。所以,基本上,你在寻找错误的答案

让我们以骰子为例。使用secure random就像使用普通的未加载骰子。每个骰子卷独立于前一个骰子卷。不安全随机使用上一个掷骰子来确定下一个结果。(因此,如果你知道上一次掷骰子是6,你可以预测下一次掷骰子)

因此,如果给定前面的随机数列表,用户/黑客/管理员/等可以预测出现的数字,那么您基本上必须确定这是否是应用程序的问题。(在大多数情况下,这将是一个问题)。如果你只是想用随机数来选择一个随机的东西来显示在网页上,普通的随机数是可以的。如果您想使用随机数进行安全、游戏或交易,最好使用SecureRandom


我不确定,但我认为使用SecureRandom的开销增加很小。所以随机的稍微快一点。但在大多数情况下,这种速度的提高并不值得当你们滥用不安全随机数生成器的不安全性时出现的潜在问题。

一般来说,你们是一个关于随机数的常见错误信念的受害者:随机序列并不意味着一个数不能在该序列中重复。恰恰相反,它必须以很高的概率出现。这种误解实际上是用来区分人类产生的“随机”序列和真实序列。人类生成的0和1的“随机”序列可能如下所示:

0,1,0,1,1,0,1,0,0,0,1,0,1,0

虽然一个真正的随机序列并不羞于重复相同的数字两次以上:)一个很好的例子是,它也寻找重复

这两种生成器都具有良好的“统计特性” 人们还普遍错误地认为,加密安全的随机数会以某种方式产生“更随机”的值。它们的统计概率可能非常相似,并且在那些标准的统计测试中都会表现得非常好

在哪里使用哪个 因此,它实际上取决于您想做什么,您的选择应该是PRNG还是加密安全PRNG(CSPRNG)。“正常”PRNG对于模拟目的(如蒙特卡罗方法等)来说非常好。CSPRNG的额外好处是不可预测性。因为CSPRNG可以“做得更多”,所以其性能也很可能比香草PRNG差

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

经验法则在哪里使用哪个是

  • 您在“敌对”环境中使用CSPRNG,您不希望外部人员能够猜测敏感信息(会话ID、赢得/失去真实金钱的在线扑克等)
  • 而PRNG处于一个仁慈的环境中,你只需要良好的统计特性,而不关心可预测性(蒙特卡罗模拟、单人扑克对电脑、一般的电脑游戏)——也就是说,如果有人能够成功预测这些随机数,就不会赢到钱,也不会失去生命

好的,另外根据我读到的文章,我了解到高质量的随机性很重要,它是由SecureRandom提供的