問題描述
不久前,我開發了一個用戶可以購買門票的 Web 應用程序.由于我們客戶的流程運作方式,您購買后實際上得到的是一個包含票號的 URL.
A while ago I worked on a web application where users could buy tickets. Due to the way our client's processes worked, what you effectively got as a result of your purchase was a URL with the ticket number in it.
這些是在中東購買房產的門票,每張門票的潛在價值約為 3,000,000 美元.顯然,拋出順序整數是個壞主意.我們使用 GUID,因為它們基本上無法猜測,但我的問題是:它們足夠安全嗎?
These were tickets to buy property in the Middle East, and each ticket was potentially worth around $3,000,000. Clearly dishing out sequential integers would have been a bad idea. We used GUIDs as they're basically unguessable, but my question is: are they secure enough?
據我了解,.NET 生成的 GUID 完全是偽隨機的(除了一些不變的位).但是,我不知道使用什么算法來生成它們.
As I understand it, the GUIDs .NET produces are totally pseudo-random (except for a few non-varying bits). However, I don't know what algorithm is used to generate them.
MSDN 文檔告訴我們 Random
快速且不安全,并且 RNGCryptoServiceProvider
既慢又安全.也就是說,可以合理地假設有人可以付出足夠的努力來預測 Random
的結果,而不是 RNGCryptoServiceProvider
的結果.
The MSDN documentation tells us that Random
is fast and insecure, and RNGCryptoServiceProvider
is slow and secure. That is, it's reasonable to assume someone could put in enough effort to predict the outcome of Random
, but not of RNGCryptoServiceProvider
.
如果您看到足夠長的 GUID 序列,是否可以預測未來的 GUID?如果是,你需要看多少個?
If you saw a long enough sequence of GUIDs, would it be possible to predict futures ones? If so, how many would you need to see?
[在我們的特殊情況下,稍后會進行物理安全檢查 - 您必須出示您用來買票的護照 - 所以如果有人猜到了某人也不會太糟糕else 的 GUID,所以我們當時并沒有出汗.使用 GUID 作為數據庫鍵的便利性使其成為一種有用的數據類型.]
[In our particular case there were physical security checks later on - you had to present the passport you used to buy your ticket - so it wouldn't have been too bad if someone had guessed someone else's GUID, so we didn't sweat it at the time. The convenience of using the GUID as a database key made it a useful datatype to use.]
所以答案是不夠".
使用以下 0xA3 的答案,以及來自 question 他鏈接到,以下代碼將生成一個加密隨機 GUID,該 GUID 對 RFC 4122 的第 4.4 節:
Using 0xA3's answer below, and following links from the question he linked to, the following code will generate a cryptographically random GUID that's valid by Section 4.4 of RFC 4122:
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);
}
這比 Guid.NewGuid()
產生 GUID 的速度要慢得多,但有 122 位的非常隨機".數據,它們是安全不可預測的.
This produces GUIDs much more slowly than Guid.NewGuid()
, but with 122 bits of "very random" data, they are safely unpredictable.
當然,任何加密隨機文本都可以作為票號,但 GUID 非常方便.:-)
Of course, any cryptographically random text would have done for a ticket number, but GUIDs are pretty handy. :-)
與其他版本 4 GUID 一樣,沒有絕對的唯一性保證,但幾率令人印象深刻.只要您的數量少于 326,915,130,069,135,865(即 sqrt(-22^122ln(0.99))) 個 GUID 同時運行,您可以 99% 以上確定沒有沖突.換句話說:如果像我一樣,如果您的應用程序幾乎所有內容都超過 int.MaxValue
,那么您的應用程序將到處出現溢出錯誤,那么您可以超過 99.99999999999999999% 確定沒有沖突(即e^-(((2^31-1)^2)/(2*2^122))).這比您確信隕石不會在應用程序上線后的一秒鐘內消滅地球上的大部分生命(即 每億年一個).
As with other version 4 GUIDs there's no absolute guarantee of uniqueness, but the odds are impressive. So long as you have fewer than 326,915,130,069,135,865 (i.e. sqrt(-22^122ln(0.99))) GUIDs in play simultaneously, you can be more than 99% sure there are no collisions. Put another way: if like mine your application will have overflow errors all over the place if you have more than int.MaxValue
of pretty much anything, you can be more than 99.9999999999999999% sure of no collisions (i.e. e^-(((2^31-1)^2)/(2*2^122))). This is about a thousand times more sure than you can be that a meteorite won't wipe out most of life on Earth within one second of the application going live (i.e. one per 100 million years).
推薦答案
UUID/GUID 由 RFC4122.雖然版本 4 UUID 是從隨機數創建的 Section 6 明確安全聲明:
UUIDs/GUIDs are specified by RFC4122. Although Version 4 UUIDs are created from random numbers Section 6 makes an explicit statement on security:
不要假設 UUID 很難猜出;它們不應該被使用作為安全能力(僅僅擁有授權的標識符訪問),例如.一個可預測的隨機數源將加劇局勢.
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.
在這個問題中也可以找到關于 GUID 隨機性的一個很好的討論:
A good discussion of the randomness of GUIDs can also be found in this question:
System.Guid.NewGuid() 有多隨機?(拍兩張)
這篇關于GUID 的安全性如何?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!