如何使用 boost::random_device 生成加密安全的 64 位整数
How do I use boost::random_device to generate a cryptographically secure 64 bit integer?
我想做这样的事情:
boost::random_device rd;
boost::random::mt19937_64 gen(rd());
boost::random::uniform_int_distribution<unsigned long long> dis;
uint64_t value = dis(gen);
但我读到梅森捻线机在密码学上并不安全。但是,我也读到random_device可能是,如果它从/dev/urandom 中提取数据,这可能是在 linux 平台(我的主要平台(上。因此,如果random_device是不确定随机的,并且用于播种 mersenne twister(如上所示(,这是否也使 mersenne twister 在加密上是安全的(即使它本身不是(?
我在这个领域有点新手,所以任何建议都值得赞赏。
那么,如何生成可存储在uint64_t中的加密安全 64 位数字?
谢谢
本。
分析你的问题比看起来更难:
你用 rd()
播种 mersenne twister,它返回一个unsigned int
,因此(在大多数平台上(最多包含 32 个随机位。
从这一点开始,Mersenne Twister所做的一切都由这32位决定。
这意味着value
只能采用 2**32 个不同的值,如果存在任何攻击媒介通过蛮力攻击您使用此数字所做的任何事情,这可能是一个问题。事实上,Mersenne Twister 的播种例程甚至可能减少第一个结果的可能值的数量,因为它在其完整状态下分布了 32 个随机位(为了确保不是这种情况,您必须分析种子例程提升用途(。
然而,在这种情况下,mersenne twister 的主要弱点(其状态可以在看到 624 个数字后导出(甚至不感兴趣,因为您生成的序列非常短(1 个值(。
生成 64 个加密安全位
假设unsigned int
等效于平台上的uint32_t
,您可以使用boost::random_device
轻松生成 64 个加密安全的随机位:
boost::random_device rd;
std::uint64_t value = rd();
value = (value << 32) | rd();
这是相当安全的,因为Linux和Windows的实现都使用操作系统自己的加密安全随机源。
使用任意分布生成加密安全值
虽然以前的方法效果很好,但您可能希望使用更灵活的解决方案。这很容易做到,因为你实际上也可以使用Boost提供的随机分布random_device
。一个简单的例子是像这样重写以前的解决方案:
boost::random_device rd;
boost::random::uniform_int_distribution<std::uint64_t> dis;
std::uint64_t value = dis(rd);
(虽然理论上也可以提供更健壮的解决方案,如果前一个实际上不包含 [0, 2**32] 中的数字(,但这在实践中不是问题。
与生成器的绑定分布
为了提高可用性,您经常会发现使用 boost::bind
将发行版和生成器绑定在一起。由于boost::bind
复制了它的参数,并且复制 ctor 被删除了boost::random_device
,你需要使用一个小技巧:
boost::random_device rd;
boost::random::uniform_int_distribution<std::uint64_t> dis;
boost::function<std::uint64_t()> gen = boost::bind(dis, boost::ref(rd));
std::uint64_t value = gen();
将随机设备仅用于种子设定在加密上并不真正安全。然后将问题简化为找出初始种子,这是一个大大减少的问题。相反,直接使用随机设备。
val = dis(rd(;
为了提高安全性,请使用 /dev/random
而不是 /dev/urandom
初始化随机设备。 如果没有足够的"熵",/dev/random
会阻塞,直到发生一些随机的事情。但是,它可能要慢得多。
顺便说一句,假设您有一个高质量的 C++11 实现,它不会返回 entropy
函数的虚假值,如果您尝试删除依赖项,使用 C++11 可能是更好的主意。
编辑:显然有一些关于/dev/random是否比/dev/urandom更好的争论。我向你推荐这个。
- 从不同线程使用int64的不同字节安全吗
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 虚拟决赛作为安全
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- AES加密到解密未正确输出
- 如何将元素添加到数组的线程安全函数?
- C++中的线程安全删除
- 通过网络、跨平台传递std::变体是否安全
- 在std::thread中,joinable()然后join()线程安全吗
- 使用std::istream::peek()总是安全的吗
- 创建加密安全密码.并验证它是否有效
- 我们如何使std::uniform_int_distribution加密安全
- 我是否需要在 OpenSSL 1.1.0+ 中使用加密锁定函数来实现线程安全?
- std::random_device 加密安全吗?
- 使用Microsoft安全支持提供程序接口 (SSPI) 对消息进行加密和签名
- Qt/C++(跨平台)中加密安全的伪随机数生成器
- 如何在Windows Phone上使用c++/cx获得加密安全随机性
- 如何使用 boost::random_device 生成加密安全的 64 位整数
- 这种加密方法安全吗
- 我可以从random_device和mt19937的组合中生成加密安全的随机数据吗