Java和密码强随机数

时间:2011-01-13 16:32:08

标签: java android encryption salt

我一直在使用Java的SecureRandom类来生成盐,以便以后加密和密码哈希(我为每个任务生成单独的盐)。我一直使用的代码如下:

//Init random number generator
secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(System.nanoTime());

//Create salts
secureRandom.nextBytes(bytAuthSalt);
secureRandom.nextBytes(bytEncryptionSalt);

现在,一切都很顺利,直到我开始真正验证我得到的值。对于应用程序的几个连续执行,我的盐是:

[B@43d55dd8
[B@43d55b58
[B@43d55b50
[B@43bd0cc8
[B@43db0b08
[B@43bd0f50

我对这些数字看起来大致是连续的这一事实感到不安。在网上进行了一些搜索之后,我再次重复了这些运行而没有将它自己播种到相同的结果。

我唯一猜测可能导致这种情况的原因是我正在为Android平台开发。我知道他们有自己的加密提供商,但我没有任何例外。任何想法?

提前致谢。

4 个答案:

答案 0 :(得分:9)

看起来您正在打印对字节数组的引用而不是其内容。这就是为什么它们是顺序的,引用基本上是给你JVM内存中的位置。在打印之前将字节数组转换为String。

String saltContents = Arrays.toString(bytAuthSalt);

使用Arrays将数组转换为String将显示字节的原始值。

答案 1 :(得分:4)

似乎您正在打印数组,而不是实际值。 “[B @”告诉你它是一个字节数组,并且它后面的所有对象都是id。
尝试这样的事情:

System.out.println("bytAuthSalt");
  for (byte b : bytAuthSalt) {
    System.out.print(b);
  }
  System.out.println();

或者这个:

Arrays.toString(bytAuthSalt);

这将打印数组中的所有值。

答案 2 :(得分:2)

SHA1PRNG仅与其种子一样安全。出于这个原因,使用System.nanoTime()作为种子是一个可怕的想法。可以充分缩小播种时间范围的攻击者可以尝试所有可能的值,直到找到匹配的序列。攻击者得益于System.nanoTime()的分辨率通常远大于1纳秒。

最好只做new SecureRandom()以允许JRE选择最佳实现。在大多数平台上,这将使用OS原生熵源来种子RNG,例如/dev/random

答案 3 :(得分:1)

我还建议不要用于播种System.nanoTime(),因为它不能保证在所有平台上都能正常工作。在某些情况下,它只返回'零',我认为它不适合播种RNG。