SecureRandom会减少伪随机数据的熵吗?

huangapple go评论78阅读模式
英文:

Does SecureRandom reduce entropy of pseudo-random data?

问题

我在思考在Docker容器中生成随机(或伪随机)序列,但遇到了另一个有趣的行为。

直接从/dev/urandom读取8000000字节,并使用ENT进行测试,结果如下:

每字节熵=7.999976比特。

最佳压缩可以将此8000000字节文件的大小减小0%。

8000000个样本的卡方分布为262.08,随机情况下超过此值的概率为36.69%。

数据字节的算术平均值为127.5337(127.5 = 随机)。
圆周率的蒙特卡洛值为3.139911785(误差为0.05%)。
序列相关系数为-0.000101(完全不相关= 0.0)。

但是在生成1000000个DES密钥的情况下,ENT的输出如下:

每字节熵=6.999990比特。

最佳压缩可以将此8000000字节文件的大小减小12%。

8000000个样本的卡方分布为8000217.63,随机情况下超过此值的概率低于0.01%。

数据字节的算术平均值为127.4870(127.5 = 随机)。
圆周率的蒙特卡洛值为3.145497786(误差为0.12%)。
序列相关系数为0.000033(完全不相关= 0.0)。

用于生成1000000个密钥的代码如下:

KeyGenerator des = KeyGenerator.getInstance("DES");
IntStream.range(0, 1_000_000).forEach(j -> {
    SecretKey secretKey = des.generateKey();
    System.out.write(secretKey.getEncoded());
});

熵较低,卡方分布显示分布不再是随机的。

因此,我在想Java的SecureRandom实现是否只是降低了熵,并且直接从urandom中读取值可能是一个更好的选择。

英文:

I was wondering about random (or pseudo random) sequence generation in Docker containers,
but came across another interesting behavior.

When reading 8000000 bytes directly from /dev/urandom and testing result with ENT gives the following:

Entropy = 7.999976 bits per byte.

Optimum compression would reduce the size
of this 8000000 byte file by 0 percent.

Chi square distribution for 8000000 samples is 262.08, and randomly
would exceed this value 36.69 percent of the times.

Arithmetic mean value of data bytes is 127.5337 (127.5 = random).
Monte Carlo value for Pi is 3.139911785 (error 0.05 percent).
Serial correlation coefficient is -0.000101 (totally uncorrelated = 0.0).

But in case of generating 1000000 DES keys the output of ENT gives the following:

Entropy = 6.999990 bits per byte.

Optimum compression would reduce the size
of this 8000000 byte file by 12 percent.

Chi square distribution for 8000000 samples is 8000217.63, and randomly
would exceed this value less than 0.01 percent of the times.

Arithmetic mean value of data bytes is 127.4870 (127.5 = random).
Monte Carlo value for Pi is 3.145497786 (error 0.12 percent).
Serial correlation coefficient is 0.000033 (totally uncorrelated = 0.0).

Code used to generate 1000000 keys:

KeyGenerator des = KeyGenerator.getInstance("DES");
IntStream.range(0, 1_000_000).forEach(j -> {
    SecretKey secretKey = des.generateKey();
    System.out.write(secretKey.getEncoded());
});

Entropy is lower and Chi square distribution shows that distribution is not random anymore.

So I am wondering if SecureRandom implementation of Java just reduces an entropy and reading values directly from
urandom might be a better choice.

答案1

得分: 1

这里没有显示出SecureRandom存在问题。

你在DES密钥中得到"每字节只有7位熵"的结果,是因为DES密钥本来就是这样的。DES密钥长度为8字节,但其中的64位中只有56位(即每字节7位)是随机的。每个字节中的第8位被保留为该字节的奇偶校验位。奇偶校验位的值显然与其他7位的值高度相关,因此该位并不随机。有关更多背景信息,请参阅维基百科上的DES页面

如果你尝试使用一个使用全随机密钥的算法(比如"AES")来进行测试,你应该会得到一个更令人放心的结果。

英文:

Nothing here indicates a problem with SecureRandom.

You're getting the "only 7 bits of entropy per byte" result for your DES keys because that's what DES keys have. A DES key is 8 bytes long but only 56 of those 64 bits (i.e. 7 bits per byte) are random. The 8th bit in each byte is reserved for use as a parity bit for that byte. The value of the parity bit is obviously highly correlated with the values of the other 7 bits, and therefore that bit is not at all random. See DES at Wikipedia for more background.

You should get a more comforting result if you try your test again with a key generator for an algorithm that uses all-random keys, like "AES".

huangapple
  • 本文由 发表于 2020年4月5日 20:22:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/61042509.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定