Java 和加密强随机数
我一直在使用 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 平台进行开发这一事实。我知道他们有自己的加密提供商,但我没有得到任何例外。有什么想法吗?
提前致谢。
I have been doing some work with Java's SecureRandom class to generate salts for later encryption and password hashing (I am generating separate salts for each task). The code I have been using is as follows:
//Init random number generator
secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(System.nanoTime());
//Create salts
secureRandom.nextBytes(bytAuthSalt);
secureRandom.nextBytes(bytEncryptionSalt);
Now, all was going fine until I started to actually verify the values that I got. For several sequential executions of the application my salts were:
[B@43d55dd8
[B@43d55b58
[B@43d55b50
[B@43bd0cc8
[B@43db0b08
[B@43bd0f50
I am disturbed by the fact that the numbers all appear to be roughly sequential. After some searching on the web, I repeated the runs again without seeding it myself to the same results.
My only guess as to what may be causing this comes from the fact that I am developing for the Android platform. I know that they have their own cryptographic providers but I do not get any exceptions. any ideas?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
看起来您正在打印对字节数组的引用而不是其内容。这就是为什么它们是连续的,引用基本上为您提供了 JVM 内存中的位置。在打印之前将字节数组转换为字符串。
使用 数组将显示字节的原始值。
It looks like you're printing out the reference to the byte array instead of its contents. This is why they're sequential, the reference is basically giving you the location in the JVM memory. Convert the byte array to a String before you print it.
Converting the array to a String using Arrays will show you the raw values of the bytes.
似乎您正在打印一个数组,而不是实际值。 “[B@”告诉你这是一个字节数组,后面的所有内容都是对象 ID。
尝试这样的事情:
或者这个:
这将打印数组中的所有值。
Seems that you are printing an array, not actual values. "[B@" tells you it's a byte array, and everything after it object id.
Try something like this:
Or this:
This would print all values in array.
SHA1PRNG 的安全性取决于其种子。因此,使用 System.nanoTime() 作为种子是一个糟糕的主意。能够充分缩小播种时间范围的攻击者可以尝试所有可能的值,直到找到匹配序列。
System.nanoTime()
的分辨率通常远大于 1 纳秒,这一事实对攻击者有所帮助。最好只执行 new SecureRandom() 来允许 JRE 选择最佳的实现。在大多数平台上,这将使用操作系统本机熵源来播种 RNG,例如
/dev/random
。SHA1PRNG is only as secure as its seed. For this reason, using
System.nanoTime()
as the seed is a horrible idea. Attacker who can narrow down the time range of the seeding sufficiently can try out all the possible values until he finds the matching sequence. The attacker is aided by the fact that resolution ofSystem.nanoTime()
is usually much bigger than 1 nano-second.It's much better to just do
new SecureRandom()
to allow JRE to pick the best possible implementation. On most platforms, this would use the OS-native entropy source to seed RNG, such as/dev/random
.我还建议不要使用 System.nanoTime() 进行播种,因为不能保证它在所有平台上都能正常工作。在某些情况下,它只返回“零”,我认为这对于播种 RNG 来说不是正确的数字。
I would also advise not to use for seeding
System.nanoTime()
, since it's not guaranteed to work properly in all platforms. In some cases it return just 'zero' which I suppose it's not right number for seeding RNG.