不久之前,我在一个用户可以购买门票的网络应用程序上工作.由于我们客户的流程的运作方式,您购买后实际获得的是一个带有票号的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产生的速度慢得多 …
在您开始将其标记为重复之前,请将我读出来.另一个问题是(很可能)不正确的接受答案.
我不知道.NET如何生成其GUID,可能只有微软这样做,但它很有可能只是调用CoCreateGuid().但是,该函数被记录为调用UuidCreate().并且用于创建UUID的算法已被很好地记录.
长话短说,尽管如此,似乎System.Guid.NewGuid()确实使用了版本4 UUID生成算法,因为它生成的所有GUID都符合标准(参见自己,我尝试了几百万个GUID,它们都匹配).
换句话说,除了一些已知位之外,这些GUID 几乎是随机的.
这再次提出了一个问题 - 随机是如何随机的?正如每个优秀的小程序员都知道的那样,伪随机数算法只与其种子(即熵)一样随机.那么种子是UuidCreate()什么?PRNG如何重新播种?它是加密强大的,或者如果两台计算机同时意外呼叫System.Guid.NewGuid(),我可以期望相同的GUID开始倾泻吗?如果收集到足够多的顺序生成的GUID,是否可以猜测PRNG的状态?
补充:为了澄清,我想知道我可以信任的随机性因此 - 我在哪里可以使用它.那么,让我们在这里建立一个粗略的"随机性"量表:
我在想到是否可以将它们用作数据库ID时,以及Guid.comb算法的实现System.Guid.NewGuid()(如NHibernate的实现方式)是否有缺陷,我就来到了这个问题.
我正在考虑使用 Guid 作为网站的随机匿名访问者标识符(存储为 cookie 客户端大小和数据库服务器端),我想要一种生成 Guids 的加密方式(以便尽量减少碰撞的机会)。
为了记录,Guid 中有 16 个字节(或 128 位)。
这就是我的想法:
/// <summary>
/// Generate a cryptographically strong Guid
/// </summary>
/// <returns>a random Guid</returns>
private Guid GenerateNewGuid()
{
byte[] guidBytes = new byte[16]; // Guids are 16 bytes long
RNGCryptoServiceProvider random = new RNGCryptoServiceProvider();
random.GetBytes(guidBytes);
return new Guid(guidBytes);
}
Run Code Online (Sandbox Code Playgroud)
有一个更好的方法吗?
编辑: 这将用于两个目的,访问者的唯一 ID 和购买的交易 ID(这将简要地作为查看/更新敏感信息所需的令牌)。
我需要能够加密和解密 php 和 vb.net 中的字符串。PHP 需要能够解密在 vb.net 中加密的字符串,而 vb.net 需要能够解密在 php 中加密的字符串。
我在两个环境中都有可以在该环境中工作的工作代码,但它们不能相互协作。
我对此进行了大量搜索,我相信这与 AES256 的 openssl 实现以及它与 IV 或类似的东西加盐的方式有关。
vb 实现为 IV 生成一个随机 GUID,并在对其进行 base64 编码之前将其添加到加密字符串中。
我的 vb.net 代码是这样的......
Imports System.IO
Imports System.Text
Imports System.Security.Cryptography
Public Class tbSecurity
Public Shared enckey = "00000000000000000000000000000000"
Public Shared Function AESEncryptStringToBase64(strPlainText As String) As String
Dim Algo As RijndaelManaged = RijndaelManaged.Create()
With Algo
.BlockSize = 128
.FeedbackSize = 128
.KeySize = 256
.Mode = CipherMode.CBC
.IV = Guid.NewGuid().ToByteArray()
.Key = Encoding.ASCII.GetBytes(enckey)
End With …Run Code Online (Sandbox Code Playgroud)