1

我正在做一个学校作业,其中一个要求是生成一个随机的 128 位数字。我想知道如何在 C# 中做到这一点,这种方法可以工作吗?

byte[] RND128NUMBYTE = new byte[128];
Random Rand = new Random();
Rand.NextBytes(RND128NUMBYTE);

谢谢大家

编辑:首先,谢谢大家的回答。无论如何,如果我明确分配会更好:我正在以安全的方式构建服务器/客户端应用程序。用户连接到服务器后,要与连接到该服务器的其他用户通信,必须对其进行身份验证。用户向服务器询问身份验证,服务器用 128 位随机数回答客户端。之后将完成一些其他过程。

4

4 回答 4

13

数组的大小以元素为单位。因此,对于一个字节数组,您需要 16 个元素,每个元素 8 位,而不是 128 个元素。

您可以使用System.Random.NextBytesRNGCryptoServiceProvider.GetBytes

但这System.Random.NextBytes可能不是一个好的选择,因为播种不好System.Random意味着您无法获得随机 128 位数字所期望的属性。例如,即使生成的数字少于 2^64,您也很可能会发生冲突。来自良好 PRNG 的 128 位数字与 GUID 一样具有全球唯一性,但从中提取的数字System.Random肯定不是。

byte[] bytes = new byte[16];
using(var rng = new RNGCryptoServiceProvider())
{
    rng.GetBytes(bytes);
}
于 2013-05-10T22:24:02.510 回答
8

首先,您正在生成 128 个随机字节,而不是随机位。但是您的澄清使一切变得不同:

我正在以安全的方式构建服务器/客户端应用程序。用户连接到服务器后,要与连接到该服务器的其他用户通信,必须对其进行身份验证。用户向服务器询问身份验证,服务器用 128 位随机数回答客户端。

在这种情况下,即使您考虑到您生成的比特数是八倍多的事实,您的解决方案也是非常非常错误的。System.Random只是伪随机的,实际上在你做种子时只有 31 位熵。(*) 为了安全起见,您需要所有 128 位熵。

请记住,每一个缺失的部分都会使问题变得容易攻击一半;如果你需要 128 位熵而你有 31 位,那么问题就不会比攻击更容易四倍问题是 2 128-31 = 10 29倍更容易攻击!

巧合的是,我刚刚写了一篇关于此的博客文章。我挑战读者找出我在Random只给出前五六张牌时洗过的一副牌的其余部分。有人在几个小时内通过蛮力找到了解决方案。随机性非常弱。. 见http://ericlippert.com/2013/05/06/produce-permutations-part-seven/

如果您需要安全系统的加密强度随机性,那么您需要使用具有超过 128 位熵的特殊用途随机源。

因此 CodeInChaos 的答案是正确的。

这个故事有两个寓意:

首先,这就是设计安全系统如此困难的原因。有很多细节需要做对,你必须把所有细节都做对,否则系统就不安全。

其次,确保您在问题中提供足够的信息以获得好的答案。


(*) 事实上,它的数量要少得多,因为这 2 31个可能的种子中的一些比其他种子更有可能。

于 2013-05-11T00:06:48.037 回答
3

不知道任务是关于什么的吗?

这样做:
实施你的理论。多次运行它并存储结果。对其进行一些统计,例如检查最低和最高值以了解您是否在限制范围内。额外计算每个结果并确保它们均匀分布。

于 2013-05-10T22:24:11.847 回答
2

要求是生成一个随机的 128 位数字

我认为这个分配有点太苛刻了,我希望他们的意思是一个伪随机数。我想指出,您必须将问题分解为您理解的部分。

您已正确初始化PRNG并知道如何让它填充字节数组

Random Rand = new Random();
Rand.NextBytes(RND128NUMBYTE);

现在你需要随机填充一个 128 位的空间。什么是 128 位,.NET 或 C# 是否为您提供对位的访问?不是直接的,但你有一个byte类型。这种类型使用 8 位,因此您只需要 128 / 8 = 16 个字节。

你快到了,你只需要创建一个 16 字节而不是 128 字节的数组:

byte[] RND128NUMBYTE = new byte[16];

如何这些字节转换为“数字”我会交给你。

于 2013-05-10T22:25:12.867 回答