在C#中随机化通用列表顺序的最佳方法是什么?我在一个列表中有一组有限的75个数字,我想为其分配一个随机顺序,以便为抽奖类型的应用程序绘制它们.
不久之前,我在一个用户可以购买门票的网络应用程序上工作.由于我们客户的流程的运作方式,您购买后实际获得的是一个带有票号的URL.
这些是在中东购买房产的门票,每张门票的价值可能在300万美元左右.显然抛出顺序整数本来是个坏主意.我们使用GUID,因为它们基本上是不可知的,但我的问题是:它们足够安全吗?
据我所知,GUIDs .NET产生的是完全伪随机的(除了一些非变量位).但是,我不知道使用什么算法来生成它们.
MSDN文档告诉我们Random快速且不安全,并且RNGCryptoServiceProvider速度慢且安全.也就是说,假设有人可以投入足够的努力来预测结果Random,但不是RNGCryptoServiceProvider.
如果您看到足够长的GUID序列,是否可以预测期货?如果是这样,你需要看多少?
[在我们的特殊情况下,之后会进行身体安全检查 - 您必须出示用于购买机票的护照 - 所以如果有人猜到别人的GUID 就不会太糟糕,所以我们没有出汗当时.使用GUID作为数据库密钥的便利性使其成为一种有用的数据类型.]
编辑:
所以答案是"不够".
使用下面的0xA3的答案,并跟随他链接的问题的链接,以下代码将生成一个加密随机GUID,该GUID由RFC 4122的第4.4节有效:
static Guid MakeCryptoGuid()
{
// Get 16 cryptographically random bytes
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] data = new byte[16];
rng.GetBytes(data);
// Mark it as a version 4 GUID
data[7] = (byte)((data[7] | (byte)0x40) & (byte)0x4f);
data[8] = (byte)((data[8] | (byte)0x80) & (byte)0xbf);
return new Guid(data);
}
Run Code Online (Sandbox Code Playgroud)
这比GUID产生的速度慢得多 …
我知道这可能听起来像一个毫无意义的问题,但是听我说...
我基本上想知道我是否可以信任GUID来生成一个在100%的时间内都是唯一且无法预测的值.
我基本上是在网站的登录系统上滚动,并想知道GUID是否足够安全用于会话cookie.
在评估答案时,将非常感谢有关如何生成GUID的任何背景知识.
感谢您提供重复问题的链接,但我的问题仅针对.Net框架.
请注意,这不是我的应用程序,它是我正在为客户端测试的应用程序.我通常会在https://security.stackexchange.com/上提出这样的问题,但是因为这是我在这里提出的更多编程相关问题.
当然,UUID的RFC 4122没有规定必须由密码安全伪随机数发生器(CSPRNG)生成类型4 UUID.它简单地说
将所有其他位设置为随机(或伪随机)选择的值.
虽然,算法的某些实现(例如Java中的这种实现)确实使用CSPRNG.
我试图深入研究微软的实施是否成功.主要围绕.NET或MSSQL Server如何生成它们.
检查.NET源代码,我们可以看到以下代码:
Marshal.ThrowExceptionForHR(Win32Native.CoCreateGuid(out guid), new IntPtr(-1));
return guid;
Run Code Online (Sandbox Code Playgroud)
检查CoCreateGuiddocco,它说
CoCreateGuid函数调用RPC函数UuidCreate
我能找到关于这个功能的所有内容都在这里.我好像已经到了兔子洞的尽头.
现在,有没有人知道如何UuidCreate生成其UUID?
我见过很多相关帖子:
第一个说:
GUID不保证随机性,它保证了唯一性.如果您想要随机性,请使用Random生成字符串.
我同意这一点,除了在我的情况下随机,不可预测的数字,你当然使用CSPRNG而不是Random(例如RNGCryptoServiceProvider).
而后者的状态(实际上引自维基百科):
WinAPI GUID生成器的密码分析显示,因为V4 GUID的序列是伪随机的; 在完全了解内部状态的情况下,可以预测先前和后续的值
现在,在围栏的另一边,Will Dean说这篇文章
我最后一次研究这个问题(几年前,可能是XP SP2),我直接进入操作系统代码,看看实际发生了什么,并使用安全随机数生成器生成一个随机数.
当然,即使它当前正在使用CSPRNG,这也将是特定于实现的,并且可能随时更改(例如,对Windows的任何更新).不太可能,但理论上可行.
我的观点是,没有规范的参考,以上是为了证明我已经完成了我的研究,上述帖子都没有引用任何权威的内容.
原因是我正在尝试确定是否需要更改使用GUID进行身份验证令牌的系统.从纯粹的设计角度来看,答案肯定是肯定的,但是从实际的角度来看,如果Windows UuidCreate功能确实使用了CSPRNG,那么系统就没有直接的风险.任何人都可以对此有所了解吗?
我正在寻找有信誉的来源的任何答案来支持它.
是否及时订购了GUID?我的意思是如果你使用带有GUID变量类型的ORDER BY,最近创建的记录会迟到吗?
由于GUID生成是时间相关的,如果在不同线程上的同一时刻多次调用System.Guid.NewGuid(),它是否可以返回相同的GUID?
在.NET中编写函数以生成基于种子的GUID的最简单方法是什么,这样我才能对其唯一性有更大的信心?
string GenerateSeededGuid(int seed) { /* code here */ }
Run Code Online (Sandbox Code Playgroud)
理想情况下,种子将来自CryptGenRandom,它描述了它的随机数生成如下:
此函数生成的数据是加密随机的.它比典型的随机数生成器(如C编译器附带的生成器)生成的数据更随机.
此函数通常用于生成随机初始化向量 和salt值.
软件随机数生成器的工作方式基本相同.它们以随机数开始,称为种子,然后使用算法基于它生成伪随机比特序列.这个过程中最困难的部分是获得一个真正随机的种子.这通常基于用户输入延迟或来自一个或多个硬件组件的抖动.
使用Microsoft CSP,CryptGenRandom使用其他安全组件使用的相同随机数生成器.这允许许多过程对系统范围的种子做出贡献.CryptoAPI为每个用户存储一个中间随机种子.为了形成随机数生成器的种子,调用应用程序提供它可能具有的位 - 例如,鼠标或键盘定时输入 - 然后将其与存储的种子和各种系统数据以及用户数据(例如进程ID和线程ID,系统时钟,系统时间,系统计数器,内存状态,可用磁盘集群,散列用户环境块.该结果用于对伪随机数发生器(PRNG)进行种子处理.[...]如果一个应用程序可以访问一个好的随机源,它可以填充在调用CryptGenRandom之前,pbBuffer缓冲区包含一些随机数据 .然后,CSP使用此数据进一步随机化其内部种子.在调用CryptGenRandom之前省略初始化pbBuffer缓冲区的步骤是可以接受的 .
我已经在线搜索了多个资源,但到目前为止还无法找到一个明确的答案,即微软的GUID生成机制是否足够安全以保证它可以作为整个应用程序的唯一ID使用.
为了澄清,'足够安全',我的意思是询问用于生成GUID的算法是否具有任何已知的弱点或漏洞,这些弱点或漏洞可能会降低GUID的有效随机性,即导致不可忽略的冲突次数.如果不是,这是否意味着GUID是完全不可行的,如果是,有一些方法可以为GUID生成器函数设定种子,以有效地增加生成的GUID的随机性.
基于在MSDN引导这里(中指定的信息http://msdn.microsoft.com/en-us/library/system.guid.aspx)是没有任何迹象表明用于生成GUID该系统可以在要被依赖足够随机.
谢谢!