根据Microsoft关于NEWSEQUENTIALID
的文档,NEWSEQUENTIALID的输出是可预测的。但可预测性到底有多高呢?假设我有一个由NEWSEQUENTIALID
生成的GUID,这有多难:
- 计算下一个值?
- 计算前一个值?
- 计算第一个值?
- 计算第一个值,甚至不知道任何GUID的所有?
- 计算行数?例如,当使用整数时,
/order?id=842
告诉我应用程序中有842个订单。
下面是一些关于我正在做的事情的背景信息,以及各种权衡是什么。
使用GUID而不是整数作为主键的安全性好处之一是GUID很难猜测。例如,假设黑客看到一个URL,如/user?id=845
,他可能会尝试访问/user?id=0
,因为很可能数据库中的第一个用户是管理用户。此外,黑客可以迭代/user?id=0..1..2
以快速收集所有用户。
/order?id=482
告诉我,自从网店上线以来,已经有482个订单了。
不幸的是,使用GUID作为主键有众所周知的性能缺点。为此,SQL Server引入了NEWSEQUENTIALID
功能。在这个问题中,我想了解NEWSEQUENTIALID
的输出是如何可预测的。
底层操作系统功能为UuidCreateSequential
。该值来自网卡的MAC地址和每个操作系统引导的增量值。看到RFC4122。SQL Server做一些字节变换来使结果排序正确。所以从某种意义上说,价值是高度可预测的。具体来说,如果你知道一个值,你可以立即预测相似值的范围。
然而,我们不能预测id=0
的对等物,也不能预测52DE358F-45F1-E311-93EA-00269E58F20D
意味着商店卖出了至少482件商品。
唯一被"批准"的随机生成是CRYPT_GEN_RANDOM
(包含CryptGenRandom
),但这显然是一个可怕的关键候选。
在大多数情况下,下一个newsequentialid
可以通过取当前值并在第一个十六进制对上加1来预测。
换句话说:
1 e 29 ps3 - 45 - f1 - e311 - 80 - ca - 00155 - d008b1c
后面跟着
1 f 29 ps3 - 45 - f1 - e311 - 80 - ca - 00155 - d008b1c
后面跟着
2029 ps3 - 45 - f1 - e311 - 80 - ca - 00155 - d008b1c
偶尔,序列将从一个新值重新开始。
所以,这是非常可预测的
NewSequentialID
是windows函数UuidCreateSequential
的包装器
你可以试试下面的代码:
DECLARE @tbl TABLE (
PK uniqueidentifier DEFAULT NEWSEQUENTIALID(),
Num int
)
INSERT INTO @tbl(Num) values(1),(2),(3),(4),(5)
select * from @tbl
在我的机器上,此时的结果是:
PK Num
52DE358F-45F1-E311-93EA-00269E58F20D 1
53DE358F-45F1-E311-93EA-00269E58F20D 2
54DE358F-45F1-E311-93EA-00269E58F20D 3
55DE358F-45F1-E311-93EA-00269E58F20D 4
56DE358F-45F1-E311-93EA-00269E58F20D 5
你应该在不同的时间/日期尝试几次来插入行为。我试着运行了几次,第一部分每次都在变化(你看到的结果是:52…,53…,54…等等)。我等了一段时间来检查它,过了一段时间,第二部分也增加了。我想增量会持续到所有部分。基本上它看起来像简单的+=1
增量转换成Guid。
如果你想要顺序GUID并且你想要控制值,你可以使用Sequences。
示例代码:
select cast(cast(next value for [dbo].[MySequence] as varbinary(max)) as uniqueidentifier)
•计算下一个值?是的
微软表示:如果担心隐私,请不要使用此功能。可以猜测下一个生成的GUID的值,从而访问与该GUID关联的数据。
所以有可能得到下一个值。如果有可能得到之前的信息,我找不到。
从:http://msdn.microsoft.com/en-us/library/ms189786.aspx
编辑:关于NEWSEQUENTIALID和安全性的几句话:http://vadivel.blogspot.com/2007/09/newid-vs-newsequentialid.html
编辑:NewSequentialID包含服务器的MAC地址(或其中之一),因此,知道一个顺序ID可以为潜在的攻击者提供信息,这些信息可能对安全性或DoS攻击很有用。使用NewSequentialID有什么缺点吗?