Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 创建加密安全的密码。并验证它是否有效_C++_Security_Random_Cryptography_Passwords - Fatal编程技术网

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

C++ 创建加密安全的密码。并验证它是否有效,c++,security,random,cryptography,passwords,C++,Security,Random,Cryptography,Passwords,我正在开发一个也能生成密码的软件。它基本上是这样做的: 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

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

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]);
}
静态字符允许字符[]={…}
静态int passwordLength=123;
std::字符串密码;
std::随机_装置rd;
标准:mt19937 mt(rd());
标准:均匀分布区(0,sizeof(AllowedChars)-1);
for(int i=0;i
我怎么知道这个算法创建了加密安全的密码?

我知道,
random\u device
依赖于编译器、目标平台、它自己的版本等。我也不能依赖像
std::random\u device::entropy
这样的方法的输出,因为它可能只是一个固定值。见:

我也无法对其输出进行黑盒测试:

我如何知道使用了哪个“随机性源”(即哪个RNG)?如果种子有足够的熵?(显然,这必须在已编译的二进制文件上完成,因为静态源代码无法揭示这些细节。)
通过此输出,我可以验证是否使用了CSPRNG。

基于Mersenne Twister
的数字生成器在加密方面不安全

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

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

一致性非常重要,不仅密码是“随机”的,而且是一致的

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

我看到这句话的最好方式是回答:

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

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


如果您使用的是
C
,为什么不直接使用
libnadium
来处理随机字节,这样做既优雅又安全。

可能不会,因为Mersenne twister算法不安全,而且算法的状态很可能是可以确定的,特别是如果有足够的输出可用的话。不幸的是,
passwordLength
整数设置为123太高了。所以这可能会泄露信息。相反,您可以尝试直接使用而不是
mt19937
。在我看来,没有特殊的图书馆需要。但是,您必须确保您的
std:random\u设备的版本是安全的(作为加强std:library的一部分)

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

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


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


创建自己的
uniform\u random\u bit\u生成器
(替换代码< MT1937 和随机设备将是这样做的一种方式,所以您可以使用其他<代码> STD:< /Cult>功能。它仅在C++ 20中指定,所以,是的,到达那里。

如果您想创建这样的密码,为什么不只用散列摘要?ShA-3有可能。y以输出摘要,只要您愿意。由于mt19937在加密方面不安全,我会自动怀疑是否使用它。还要注意的是,有一些算法具有更小的状态空间和代码大小,初始化和采样速度更快,并且在统计上“更好”在C++中输出至少<代码> STD::MT1937 。但是Mersenne Twister不是密码安全的(如答案之一所说),这是正确的,不管<代码> RealthyDebug <代码>是如何最终在“编译二进制”中实现的(无论是作为加密RNG还是其他方式),或者它最终使用的“熵源”。“例如,共享