在学习初学者的加密课程时,我试图掌握Java的SecureRandom对象。我想我的理解是:

a)不管您知道一个随机数序列有多长时间,都无法预测序列中的下一个随机数。

b)不管您知道一个随机数序列有多长时间,除了蛮力猜测外,都无法知道是使用哪一个种子开始的。

c)您可以请求各种大小的安全随机数。

d)您可以使用各种不同大小的值播种新创建的SRNG。您创建并使用相同值播种的每个新创建的SRNG都会产生相同的随机数序列。

我应该补充一点,我假设此代码在Windows上使用:

Random sr = SecureRandom.getInstance("SHA1PRNG", "SUN");

我的基本理解正确吗?提前致谢。

对于那些在加密方面相当熟练的人,我还有其他问题。它们涉及为SRNG植入种子,而不是让其在首次使用时自行植入。

e)如果您使用一个长整数而不是一个8字节的数组播种SRNG,会对生成的随机数产生什么区别(如果有)?

f)如果我用256个字节作为SRNG的种子,是否还有其他种子可以产生相同的随机数序列?

g)是否有某种最佳种子大小?在我看来,这可能是一个毫无意义的问题。

h)如果我通过使用256个字节的SRNG作为种子来加密明文,然后使它生成与明文中的字节进行XOR的随机字节,那么窃听者解密所得密文有多容易?需要多长时间?我是否认为窃听者必须知道,猜测或计算256字节种子是正确的?

我看过以前有关SecureRandom的问题,但似乎没有一个能回答我的特殊问题。
如果这些问题中的任何一个看起来过于愚蠢,我想重申一下,我是研究该领域的初学者。我很感谢任何输入,因为我想了解Java SecureRandom对象如何在密码学中使用。

最佳答案

OK,依次为:

a)正确

b)正确

c)正确,您甚至可以使用nextInt(n)请求范围为[0,n)的数字

d)正确无误:SHA1PRNG的实现未由任何算法公开定义,并且有迹象表明该实现已随时间更改,因此仅对Sun提供程序(仅对特定的运行时配置)如此

e)因为API明确表明使用了long内的所有字节(“使用给定long种子中包含的八个字节”),所以添加到状态的熵的数量应该没有任何区别

请注意,快速检查表明setSeed(long)的行为与setSeed(byte[])完全不同,主要区别在于long值的种子始终与从系统中检索到的随机性混合在一起,即使它是构造SecureRandom实例之后的第一个调用。

f)是-无限数量的种子产生相同的流;由于使用了散列函数,因此虽然找不到

g)如果混合其他熵,则熵越大越好,但没有最小值;如果将其用作唯一的种子,则不应以少于20个字节的种子开始,即:如果要使种子保持与PRNG的内部状态相同的安全性约束

我还要补充一点,如果您使用的熵少于64个字节,那么您肯定会处于危险区域。请注意,熵的1位并不总是意味着字节中的1位。大小为8的字节数组可以具有64位或更小的熵。

h)基本上是基于哈希的流密码;它是安全的,因此攻击者几乎没有机会(假设您不重用种子),但是它极其不可靠(请参阅答案d)并且流密码很慢,因此请永远不要这样做-将Cipher"AES/CTR/NoPadding"或改为"AES/GCM/NoPadding"

07-28 02:03