生成随机位序列
本文关键字:随机 | 更新日期: 2023-09-27 18:30:07
我正在尝试生成一个包含给定长度的绝对随机键的文件,假设 100 位并将它们存储在一个文件中。最好的方法是什么,哪种语言提供最好的库?提前谢谢。
随机性具有不同级别的"强度";您可以获得真正的随机位或伪随机位。真正的随机比特从现实世界的来源中获得熵。伪随机位产生一系列看似随机但实际上是可预测的位。
生成密钥时,应始终使用指定为具有加密强度的随机性生成器。这些随机位发生器经过精心设计,具有真正的不可预测性。切勿使用较弱的随机源来生成密钥。
在 C# 中,可以通过创建正确命名的随机数生成器加密服务提供程序的实例,然后调用 GetBytes 来获取所需长度的随机字节数组来实现此目的。
不用说:在生成自己的加密密钥时要非常小心。密码学就是将密钥的安全性利用到消息的安全性中;如果您对如何生成、存储和传输密钥不是很小心,那么安全系统就会受到损害。如果您自己不是密码学专家,请考虑聘请密码学专家,而不是尝试滚动自己的密码。
我还注意到,根据您的应用程序,100 位的密钥大小可能太小,或者太大。它可能太小,因为您的算法可能容易受到密钥大小的攻击,并且它可能太大,因为某些国家/地区限制使用或导出位计数过高的加密软件。考虑咨询律师。
取决于你所说的绝对随机是什么意思。如果伪随机数生成器是可以接受的,那么C++ <random>
库是一个不错的选择。
如果您需要比这更强大的保证,那么如果您的平台具有该功能,您仍然可以使用 <random>
中的std::random_device
,它提供不确定的随机数。它甚至可以提供对加密随机数生成器的访问。您必须检查平台的文档。
#include <random>
#include <iostream>
int main() {
std::random_device r("/dev/random"); // Cryptographically secure RNG on Linux, OpenBSD, OSX, (using libc++)
unsigned int completely_random_value = r();
std::cout << completely_random_value << ''n';
}
可能与您相关的一件事是Microsoft文档中关于他们在VS11中实现random_device的注释:"在此实现中,默认生成的值不是不确定的。这是Visual Studio的C++11库的另一个不幸的实现质量问题(至少要配合其chrono::high_resolution_clock的低分辨率(。
真正的随机数不能由确定性过程生成,因此语言的选择在某种意义上并不重要。既然你说"密钥",你可能正在寻找加密密钥,通过确定性过程生成这些密钥确实非常危险,并且是许多系统崩溃的原因。
我会重新考虑整个事情 - 如果你自己生成加密密钥,你绝对应该重新考虑整个事情。业余爱好者,无论多么擅长编程,都不应该编写密码。这导致了比我数不清的更多的系统错误。
这在 C/C++ 中相对容易,假设您了解没有随机数这样的东西,而只是伪随机数:
uint8_t *randomBytes(int length)
{
uint8_t buffer = malloc(length);
for (int i = 0; i < length; i++)
{
buffer[i] = arc4random_uniform(256); // or similar random function
}
return buffer; // don't forget to free buffer when done!
}
在 Java 中,你将返回一个字节数组,如下所示:
byte[] randomBytes(int length)
{
Random rand = new Random();
byte[] buffer = new byte[length];
for (int i = 0; i < length; i++)
{
buffer[i] = (byte) rand.nextInt(256);
}
return buffer;
}
在 C# 中,它与 Java 基本相同,但有一些不同之处:
byte[] randomBytes(int length)
{
Random rand = new Random();
byte[] buffer = new byte[length];
for (int i = 0; i < length; i++)
{
buffer[i] = (byte) rand.Next(256);
}
return buffer;
}