我该如何使用boost :: random_device生成一个加密安全64位整数? [英] How do I use boost::random_device to generate a cryptographically secure 64 bit integer?

查看:784
本文介绍了我该如何使用boost :: random_device生成一个加密安全64位整数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我愿做这样的事情:

 的boost :: random_device次;
提高::随机:: mt19937_64根(RD());
提高::随机:: uniform_int_distribution<无符号长长> DIS;
uint64_t中值= DIS(根);

但我读过一个梅森倍捻机是不加密安全。不过,我也看到了,一个random_device可能是,如果从/ dev / urandom的这很可能是在Linux平台上(我的主要平台)获取数据。因此,如果random_device是非确定性随机其用于种子梅森倍捻机(如上图所示),不也让梅森倍捻机加密安全(尽管其本身而言,它不是)?

我在这个舞台上有点新手,所以任何的建议是AP preciated。

所以,我怎么能生成可存储在uint64_t中加密安全64位数字?

谢谢,

本。


解决方案

分析你的问题是难度比它看起来:

您籽梅森倍捻机RD(),它返回一个 unsigned int类型,因此(在大多数平台)最多包含32个随机比特。

这梅森倍捻机从由这32位决定了这一点做的一切。

这意味着只能取2 ** 32个不同的值,这可能是一个问题,如果任何攻击向量存在,不管你用这个号码做攻击蛮力。事实上,梅森倍捻机的种子例行甚至可能减少可能的值的数量的一个结果,因为它比其完整的状态分布在32个随机比特(确保这是不是你就必须分析种子例行提振的情况下使用)。

梅森倍捻机的主要弱点(其状态可以推导看到624号)甚至没有在这种情况下的利益但是,因为你生成一个序列,它是如此之短后(1值)。

64生成加密安全位

假设 unsigned int类型等同于 uint32_t的你的平台上,你可以很容易地生成64加密安全随机位通过使用的boost :: random_device

 的boost :: random_device次;
的std :: uint64_t中值= RD();
值=(价值<< 32)| RD();

这是相当安全的,因为对于Linux和Windows的使用操作系统自身的加密安全随机性来源的。

任意分布生成加密的安全值

虽然previous的作品不够好,你可能想要一个更灵活的解​​决方案。这是很容易通过实现,你可以实际使用的随机分布升压与 random_device 提供,以及做。一个简单的例子是将改写这样的previous解决方案:

 的boost :: random_device次;
提高::随机:: uniform_int_distribution<的std :: uint64_t中> DIS;
的std :: uint64_t中值= DIS(RD);

(尽管这在理论上也提供了更可靠的解决方案,如果previous一个不实际包含在若干[0,2 ** 32),这是在实践中没有问题)。

绑定分配到发电机

要提高可用性,你会经常发现的用法的boost ::绑定绑定分配和发电机在一起。由于的boost ::绑定复制它的参数,并拷贝构造函数为的boost :: random_device 删除,您需要使用小窍门:

 的boost :: random_device次;
提高::随机:: uniform_int_distribution<的std :: uint64_t中> DIS;
提振::函数<的std :: uint64_t中()>根=的boost ::绑定(DIS,升压:: REF(RD));
的std :: uint64_t中值=根();

I would like to do something like this:

boost::random_device rd;
boost::random::mt19937_64 gen(rd());
boost::random::uniform_int_distribution<unsigned long long> dis;
uint64_t value = dis(gen);

But I've read that a mersenne twister is not cryptographically secure. However, I've also read that a random_device could be, if its pulling data from /dev/urandom which is likely on a linux platform (my main platform). So if the random_device is non-deterministically random and its used to seed the mersenne twister (as shown above), doesn't that also make the mersenne twister cryptographically secure (even though by itself, it isn't)?

I'm a bit of a novice in this arena so any advice is appreciated.

So, how can I generate a cryptographically secure 64 bit number that can be stored in a uint64_t?

Thanks,

Ben.

解决方案

Analyzing your question is harder than it might seem:

You seed the mersenne twister with rd(), which returns an unsigned int, and therefore (on most platforms) contains at most 32 random bits.

Everything that the mersenne twister does from this point on is determined by those 32 bits.

This means that the value can only take on 2**32 different values, which can be a problem if any attack vector exists that attacks whatever you do with this number by brute force. In fact, the mersenne twister's seeding routine may even reduce the number of possible values for the first result, since it distributes the 32 random bits over its complete state (to ensure that this is not the case you would have to analyse the seed routine boost uses).

The primary weakness of the mersenne twister (its state can be derived after seeing 624 numbers) is not even of interest in this case however, since you generate a sequence that is so short (1 value).

Generating 64 cryptographically secure bits

Assuming that unsigned int is equivalent to uint32_t on your platform, you can easily generate 64 cryptographically secure random bits by using boost::random_device:

boost::random_device rd;
std::uint64_t value = rd();
value = (value << 32) | rd();

This is fairly secure, since the implementations for both linux and windows use the operating system's own cryptographically secure randomness sources.

Generating cryptographically secure values with arbitrary distributions

While the previous works well enough, you may wish for a more flexible solution. This is easy to do by realizing that you can actually use the random distributions boost provides with random_device as well. A simple example would be to rewrite the previous solution like this:

boost::random_device rd;
boost::random::uniform_int_distribution<std::uint64_t> dis;
std::uint64_t value = dis(rd);

(While this can in theory also provide a more robust solution if the previous one does not actually contain a number in [0, 2**32), this is not a problem in practice.)

Binding distribution to generator

To improve usability you will often find usage of boost::bind to bind distribution and generator together. Since boost::bind copies its arguments, and the copy ctor is deleted for boost::random_device, you need to use a little trick:

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();

这篇关于我该如何使用boost :: random_device生成一个加密安全64位整数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆