创建加密安全的密码。并验证它是否有效

fex*_*fex 2 c++ security random passwords cryptography

我正在开发一个也能生成密码的软件。它基本上是这样的:

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]);
}
Run Code Online (Sandbox Code Playgroud)

我怎么知道这个算法创建了加密安全的密码?

我知道这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。

Woo*_*ock 10

一个Mersenne Twister基于伪随机数生成器加密安全。

MT 不适合加密用途的原因是,给定一些输出,您可以开始对下一个输出进行准确预测。

加密安全要求所有原语和底层协议在不牺牲熵或均匀性的情况下加密可靠。

一致性是非常重要的,而不仅仅是密码是“随机”,但也是统一的。

例如,ECDHE 之后的共享秘密(同意的椭圆曲线点,在散列之前)很可能是一个随机秘密,但它肯定不是统一的!

我看到这个放置的最好方法是从这个答案:

“DH 密钥交换的结果是一个组元素,它在计算上与组中随机/均匀分布的元素无法区分但是,重要的是要注意均匀分布的组元素不是(阅读:必然)均匀分布的元素。分布式字符串(后者必须使每个位都等于 0,概率为 1/2,等于 1,概率为 1/2)”

因此,为了更直接地回答您的问题,如果您想构建一个密码生成器,我只需将字节数组从CSPRNG诸如/dev/(u)random或板载TRNG到十六进制进行编码,而不是构建特殊的密码字符串。如果这样做,请记住十六进制的精确格式(分隔符、大写或小写)。

如果您在使用C,为什么不直接使用libsodium,以生成随机字节,它的优雅和安全。


Maa*_*wes 5

可能不会,因为梅森扭曲器算法是不安全的,并且算法的状态可能是可以确定的,尤其是在有足够的输出可用的情况下。不幸的是,passwordLength整数设置为 123 - 太高了。所以这可能会泄露信息。相反,您可以尝试直接使用而不是. 在我看来,没有特别需要特殊的图书馆。但是,您必须确保您的版本是安全的(作为一般强化 std: 库的一部分)。std:random_device mt19937std:random_device

使用统一范围从字母表中选择密码字符的原则 - 如代码所示 - 应该被认为是正确的。要了解密码的可能强度,您可以取有效字符数的 2-log,然后将其乘以密码中的字符数。好的密码应该至少有 48 到 64 位的强度,好的密码应该在 64 位以上。当然,上面的算法没有检查你是否偶然生成了一个弱密码,所以你不能完全确定。拥有足够大的密码应该可以解决这个问题。通常,如果您允许所有字符,您可以假设每个字符最多 6.6 位ASCII 可打印字符,因此 10-12 个字符应该可以。对于十六进制,您当然希望每个字符有 4 位,对于基数 64,每个字符 6 位。

请注意,许多系统对密码有愚蠢的要求,这使该方案过于简单。系统可能需要特定数量的特殊字符或数字。密码长度的限制通常也是一个问题。


我认为使用保证使用系统 RNG 的随机数设备对安全至关重要。您可能想尝试另一个随机数生成器来执行此操作,但不幸的是,由于许多库中有许多编译选项,因此我想最后您必须确保自己。

创建您自己的uniform_random_bit_generator(替换mt19937并且random_device将是这样做的一种方式,因此您可以使用std:取决于它的其他功能。尽管该接口仅在 C++ 20 中指定,所以是的,到达那里。