【发布时间】:2020-03-28 03:41:58
【问题描述】:
我正在开发一个也可以生成密码的软件。它基本上是这样的:
static char AllowedChars[] = {...}
static int passwordLength = 123;
std::string password;
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_int_distribution<int> dist(0, sizeof(AllowedChars) - 1);
for (int i = 0; i < passwordLength; ++i) {
int index = dist(mt);
password.push_back(AllowedChars[index]);
}
我怎么知道这个算法会创建加密安全密码?
我知道random_device 依赖于编译器、目标平台、它自己的版本等。我也不能依赖像std::random_device::entropy 这样的方法的输出,因为它可能只是一个固定值。见:http://www.pcg-random.org/posts/cpps-random_device.html
我也无法对其输出进行黑盒测试:https://security.stackexchange.com/questions/83254/how-to-check-randomness-of-random-number-generators
我如何知道使用了哪个“随机性来源”(即哪个 RNG)?如果种子有足够的熵?(显然,这必须在编译后的二进制文件上完成,因为静态源代码无法揭示这些细节。) 通过这个输出,我可以验证是否使用了 CSPRNG。
【问题讨论】:
-
如果你想创建像 this 这样的密码,为什么不直接使用散列摘要呢? SHA-3 可以根据需要输出摘要。
-
由于 mt19937 在密码学上是不安全的,我会自动怀疑使用它。
-
另请注意MT isn't even a very good PRNG,有些算法具有更小的状态空间和代码大小,初始化和采样速度更快,并产生统计上“更好”的输出
-
在 C++ 中至少有
std::mt19937is well-defined。但是 Mersenne Twister 在密码学上并不安全(正如其中一个答案所说),无论random_device最终如何在“编译二进制”(无论是作为密码 RNG 还是其他)或什么“熵源”中实现,这都是正确的" 它最终会使用。
标签: c++ security random cryptography passwords