创建加密安全密码.并验证它是否有效
Create cryptographically secure passwords. And verify that it works
我正在开发一个也可以生成密码的软件。它基本上是这样做的:
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。
基于Mersenne Twister
的伪随机数生成器在加密上并不安全。
MT不适合加密目的的原因是,给定一组输出,您可以开始对下一个输出进行准确的预测。
加密安全要求所有原语和底层协议在加密上合理,而不会牺牲熵或均匀性。
统一性非常重要,不仅密码是"随机的",而且是统一的。
例如,ECDHE之后的共享密钥(商定的椭圆曲线点,在散列之前(很可能是一个随机的秘密,但它肯定不是统一的!
我看到的最好的方法是从这个答案:
"DH密钥交换的结果是一个组元素,该组元素在计算上与组中的随机/均匀分布元素无法区分。然而,需要注意的重要一点是,均匀分布的群元素不是(读作:必然(均匀分布的字符串(后者必须每个位等于 0,概率为 1/2,概率等于 1/2(">
因此,为了更直接地回答您的问题,如果您想构建密码生成器,我只会将CSPRNG
(如/dev/(u)random
或板载TRNG
(的字节数组编码为十六进制,而不是构建一个特殊的密码字符串。请记住十六进制的精确格式(分隔符,大写或小写(。
如果您使用的是C
,为什么不直接使用libsodium
来生成随机字节,它既优雅又安全。
可能不是,因为Mersenne twister算法不安全,并且算法的状态可能会确定,尤其是在有足够的输出可用的情况下。不幸的是,passwordLength
整数设置为 123 - 太高了。所以这可能会泄露信息。相反,您可以尝试直接使用std:random_device
而不是mt19937
。在我看来,没有特别需要特殊的库。但是,您必须确保您的std:random_device
版本是安全的(作为强化 std: 库的一部分(。
使用统一范围从字母表中选择密码字符的原则(如代码所示(应被认为是正确的。要了解密码的可能强度,您可以取有效字符数量的 2 个对数,然后将其与密码中的字符数相乘。好的密码应该至少有48到64位的强度,好的密码应该在64位以上。当然,使用上述算法,无法检查您是否偶然生成了弱密码,因此您无法完全确定。不过,拥有足够大的密码应该可以解决这个问题。通常,如果您允许所有ASCII 可打印字符,则可以假设每个字符最多 6.6 位,因此 10-12 个字符应该可以正常工作。对于十六进制,您当然期望每个字符 4 位,对于基数 64,每个字符 6 位。
请注意,许多系统对密码有愚蠢的要求,这使得这个方案过于简单。系统可能需要特定数量的特殊字符或数字。密码长度的限制通常也是一个问题。
我认为使用保证使用系统RNG的随机数设备对安全性至关重要。您可能想尝试另一个执行此操作的随机数生成器,但不幸的是,在许多库中有许多编译选项,最后您必须确保自己 我想.
创建自己的uniform_random_bit_generator
(替换mt19937
和random_device
将是实现此目的的一种方法,因此您可以使用依赖于它的其他std:
功能。不过,该接口仅在C++ 20 中指定,所以是的,到达那里。
- 如果变量名称不跟在 char* 后面,const char* 是否有效?
- 钳制迭代器是否有效
- 检查由括号、方括号和大括号组成的一组方括号是否有效?
- 在函数内创建的对象的范围 - 如果在函数外部存储和访问引用,它们是否有效?
- 模板签名解析为 void(void) 被 GCC 拒绝;这是否有效C++?
- 我如何知道作为参数的size_t在函数中是否有效?
- 我的运算符重载是否有效<<(流插入)左操作数不是 ostream
- C++ 返回指向函数内定义的静态数组的指针是否有效?
- 此递归模板类型定义是否有效C++?
- 将 C 函数转换为 C++ 以检查数字是否有效
- 函数参数的名称与调用函数时使用的变量相同是否有效?
- 如何检查输入是否有效?
- 如何检查用户的输入是否有效以及我正在寻找的数字?
- 在函数中按值传递 unordered_map/unordered_set 是否有效? C++
- 如何检查isupper(cstr)是否有效?
- 将 std::transform 与 std::back_inserter 一起使用是否有效?
- 只需要知道我在c ++中打印模式的方式是否有效,或者有另一种方法可以有效地做到这一点
- 如何检查字符串格式在读取C++文本文件时是否有效?
- 在 c++ 中将对象设置为等于同一类的构造函数是否有效?
- 创建加密安全密码.并验证它是否有效