System.Guid.NewGuid() 的随机性如何?(拿两个) [英] How Random is System.Guid.NewGuid()? (Take two)

查看:20
本文介绍了System.Guid.NewGuid() 的随机性如何?(拿两个)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在您开始将其标记为重复之前,请先读一遍.另一个问题的答案(很可能)是错误的.

我不知道 .NET 如何生成它的 GUID,可能只有 Microsoft 知道,但很有可能它只是调用 CoCreateGuid().然而,该函数被记录为调用 UuidCreate().用于创建 UUID 的算法是非常详细的文档.

长话短说,尽管如此,System.Guid.NewGuid() 似乎确实使用了 第 4 版 UUID 生成算法,因为它生成的所有 GUID 都符合条件(请亲眼看看,我尝试了几百万个 GUID,它们都匹配).>

换句话说,这些 GUID 几乎是随机的,除了一些已知位.

这又提出了一个问题——这个随机有多随机?正如每个优秀的小程序员都知道的那样,伪随机数算法仅与其种子(也就是熵)一样随机.那么 UuidCreate() 的种子是什么?PRNG 多久重新播种一次?它在加密方面是否强大,或者如果两台计算机不小心同时调用 System.Guid.NewGuid(),我是否可以期望相同的 GUID 开始流出?如果收集到足够多的顺序生成的 GUID,能否猜测 PRNG 的状态?

添加: 澄清一下,我想知道我相信它有多随机,因此 - 我可以在哪里使用它.所以,让我们在这里建立一个粗略的随机性"尺度:

  1. 基本随机性,以当前时间为种子.可用于在 Solitaire 中洗牌,但几乎没有其他用途,因为即使不尝试也很容易发生碰撞.
  2. 更高级的随机性,不仅使用时间,还使用其他机器特定的种子因素.也许也只在系统启动时播种一次.这可用于在数据库中生成 ID,因为不太可能出现重复项.尽管如此,这对安全性还是不利的,因为可以通过足够的努力来预测结果.
  3. 加密随机,使用设备噪声或其他高级随机源作为种子.每次调用或至少经常重新播种.可用于会话 ID、分发给不受信任的方等.

我在考虑将它们用作 DB ID 是否可以,以及 Guid.comb 算法实现与 System.Guid.NewGuid()(就像 NHibernate 那样)会存在缺陷.

解决方案

答案是:你不需要知道这些.正如对 相关问题:

<块引用>

GUID 不保证随机性,它保证唯一性.

RFC4122 中对安全性和随机性做了更强有力的声明,指定 UUID 格式:

<块引用>

不要假设 UUID 很难猜测;他们不应该被使用作为安全能力(仅仅拥有就授予的标识符访问),例如.一个可预测的随机数源将使情况恶化.

其他任何内容都是实现细节(可能会发生变化).

Windows 细节

通常,人们声称 Windows 上的行为已记录在案,因此可以保证 GUID 是加密安全的.

现在存档的[MS-SECO]附录 A 中提到的 Windows 安全概述文档:

<块引用>

虽然只有少数版本 4 GUID 需要密码随机性,Windows 中内置的所有第 4 版 GUID 的随机位被获得通过 Windows CryptGenRandom 加密 API 或等效物,使用的相同来源用于生成加密密钥.

此外,同一文档的第 2.5.5 节明确提到了秘密 GUID"的使用.值作为随机数或身份验证器.

但是:这段产品行为文档不是您通常可以作为产品安全性基础的规范(特别是在 .NET 环境中).

事实上,上面的文档描述了特定产品实施细节.即使当前的 Windows 和 .NET Framework 4.x 实现在 Windows 上生成真正随机的第 4 版 UUID 值,也不能保证 System.Guid.NewGuid 将来或其他 .NET 平台(例如 Mono、Silverlight、CF、.NET Core 等).

举个例子,.NET Core 早期版本中使用的 UUID 算法取决于平台,您可能获取版本 1 UUID(在 BSD 上).

Before you start marking this as a duplicate, read me out. The other question has a (most likely) incorrect accepted answer.

I do not know how .NET generates its GUIDs, probably only Microsoft does, but there's a high chance it simply calls CoCreateGuid(). That function however is documented to be calling UuidCreate(). And the algorithms for creating an UUID are pretty well documented.

Long story short, be as it may, it seems that System.Guid.NewGuid() indeed uses version 4 UUID generation algorithm, because all the GUIDs it generates matches the criteria (see for yourself, I tried a couple million GUIDs, they all matched).

In other words, these GUIDs are almost random, except for a few known bits.

This then again raises the question - how random IS this random? As every good little programmer knows, a pseudo-random number algorithm is only as random as its seed (aka entropy). So what is the seed for UuidCreate()? How ofter is the PRNG re-seeded? Is it cryptographically strong, or can I expect the same GUIDs to start pouring out if two computers accidentally call System.Guid.NewGuid() at the same time? And can the state of the PRNG be guessed if sufficiently many sequentially generated GUIDs are gathered?

Added: To clarify, I'd like to find out how random can I trust it to be and thus - where can I use it. So, let's establish a rough "randomness" scale here:

  1. Basic randomness, taking current time as the seed. Usable for shuffling cards in Solitaire but little else as collisions are too easy to come by even without trying.
  2. More advanced randomness, using not only the time but other machine-specific factors for seed. Perhaps also seeded only once on system startup. This can be used for generating IDs in a DB because duplicates are unlikely. Still, it's not good for security because the results can be predicted with sufficient effort.
  3. Cryptograhpically random, using device noise or other advanced sources of randomness for seed. Re-seeded on every invocation or at least pretty often. Can be used for session IDs, handed out to untrusted parties, etc.

I arrived at this question while thinking if it would be OK to use them as DB IDs, and whether the Guid.comb algorithm implementation together with System.Guid.NewGuid() (like NHibernate does it) would be flawed or not.

解决方案

The answer is: You should not need to know this. As stated in the accepted answer to a related question:

A GUID doesn't make guarantees about randomness, it makes guarantees around uniqueness.

An even stronger statement on security and randomness is made in RFC4122, which speficies the UUID format:

Do not assume that UUIDs are hard to guess; they should not be used as security capabilities (identifiers whose mere possession grants access), for example. A predictable random number source will exacerbate the situation.

Anything else is an implementation detail (and might be subject change).

Windows specifics

Often, people claim that the behavior on Windows is documented and that it is therefore guaranteed that GUIDs are cryptographically secure.

The now archived [MS-SECO] Windows Security Overview document mentions in Appendix A:

Although only a small minority of version 4 GUIDs require cryptographic randomness, the random bits for all version 4 GUIDs built in Windows are obtained via the Windows CryptGenRandom cryptographic API or the equivalent, the same source that is used for generation of cryptographic keys.

Moreover, section 2.5.5 of the same document explicitly mentions the use of "secret GUID" values as nonce or authenticator.

BUT: This piece of product behavior documentation is not a specification you can generally base the security of your product on (in particular in the context of .NET).

In fact, the document above describes an implementation detail of a particular product. Even if the current Windows and .NET Framework 4.x implementations produce truly random version 4 UUID values on Windows, there is no guarantee that System.Guid.NewGuid will do so in the future or on other .NET platforms (e.g. Mono, Silverlight, CF, .NET Core, etc).

Just as an example, the UUID algorithm used in earlier versions of .NET Core depends on the platform and you might get a version 1 UUID (on BSD).

这篇关于System.Guid.NewGuid() 的随机性如何?(拿两个)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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