前言
在业务开发中,大量场景需要唯一ID来进行标识:用户需要唯一身份标识;商品需要唯一标识;消息需要唯一标识;事件需要唯一标识…等等,都需要全局唯一ID,尤其是分布式场景下。资源ID通常也会跟水平越权联系在一起,而水平越权的一种解决方案就是生成无序不可猜测的ID。
那么当我们遇到那么看似无规律的ID时,即使存在越权也无法进行利用吗?
带着上面的问题,本篇文章就来看看常见的生成唯一ID的方式以及他们的特点。
唯一ID的特征
唯一ID的应该具备下面的一些特征:
1)唯一性:生成的ID全局唯一,在特定范围内冲突概率极小
2)可用性:可保证高并发下的可用性
3)安全性:对生成的ID不能进行预测,不会暴露系统和业务的信息
常用方式
目前常用的生成唯一ID的方式有:UUID,数据库自增ID,雪花算法,哈希算法
方案 |
唯一性 |
有序性 |
可用性 |
雪花算法 |
较强唯一性 |
大致有序 |
高可用 |
UUID |
强唯一性 |
无序 |
高可用 |
数据库自增ID |
强唯一性 |
有序 |
较高可用 |
哈希算法 |
较强唯一性 |
无序 |
较高可用 |
雪花算法
雪花算法生成的ID可以通过其组成部分进行一定程度的预测。
雪花算法生成的ID由以下几部分组成:
1)符号位:始终为0,表示正数。
2)时间戳:占用41位,表示从某个固定时间点(如2010年1月1日0时0分0秒)开始的时间差。
3)机器标识:包括数据中心ID和机器ID,分别占用5位,用于区分不同的服务器节点。
4)序列号:占用12位,用于同一毫秒内生成的不同ID
雪花算法是否可以被猜测?
我们在测试过程中,可能会遇到一些资源ID采用了雪花算法生成,那么是否可以猜测到其它的资源ID呢?
理论上是可以的,只不过比较麻烦,根据算法来看,时间戳采用毫秒,假设机器ID哪里一共有5个,一毫秒只生成一个资源ID,那么一个小时就有60*60*1000*5=18000000。
数据量太大,我们通过爆破的方式去拿信息比较困难,而且容易被发现,当攻击成本超过了收益,那么也就没有什么意义了。因此雪花算法在一定程序上也保证了安全性。
数据库自增
数据库自增ID可能是大家最熟悉的一种唯一ID生成方式,其具有使用简单,满足基本需求,天然有序的优点,但也有缺陷:
1)并发性不好
2)数据库写压力大
3)数据库故障后不可使用
4)存在数量泄露风险
数据库自增 ID 是最常见的一种生成 ID 方式。利用数据库本身来进行设置,在全数据库内保持唯一。优势是使用简单,满足基本业务需求,天然有序;缺点是强依赖 DB,会由于数据库部署的一些特性而存在单点故障、数据一致性等问题。针对上面介绍的数据库自增 ID 的缺陷,会存在以下两种优化方案:
1. 数据库水平拆分,设置不同的初始值和相同的步长
如图所示,可保证每台数据库生成的ID是不冲突的,但这种固定步长的方式也会带来扩容的问题,很容易想到当扩容时会出现无ID初始值可分的窘境,解决方案有:
-
根据扩容考虑决定步长 -
增加其他位标记区分扩容
这其实都是在需求与方案间的权衡,根据需求来选择最适合的方式。
2.批量生成一批ID
如果要使用单台机器做ID生成,避免固定步长带来的扩容问题,可以每次批量生成一批ID给不同的机器去慢慢消费,这样数据库的压力也会减小到N分之一,且故障后可坚持一段时间。
如图所示,但这种做法的缺点是服务器重启、单点故障会造成ID不连续。还是那句话,没有最好的方案,只有最适合的方案。
UUID
UUID是一套用于生成全局唯一标识符的标准,也被称为GUID (Globally Unique Identifier),通过使用UUID可以在分布式系统中生成唯一的 ID,UUID的生成方式有多种。
UUID格式
UUID的标准形式为32个十六进制数组成的字符串,且分隔为五个部分,如:
467e8542-2275-4163-95d6-7adc205580a9
各部分的数字个数为:8-4-4-4-12
在系统中使用时一般会去掉-。那么就是下面的格式:467e85422275416395d67adc205580a9
特征
唯一性:基于随机数和时间戳组合,生成全局唯一的ID
无序性:UUID是随机生成的,不具有时间排序性
性能:UUID的生成速度较快,适合高并发环境
UUID可以抵御越权吗?
UUID完全无序,不能够进行猜测,可以防止水平越权攻击
哈希算法
哈希算法可用于生成唯一ID,但需要理解哈希算法的特性和限制。哈希算法将任意长度的输入数据转化为固定长度的哈希值,这个哈希值通常是一个固定长度的二进制串,通常以十六进制表示。
哈希原理
-
哈希算法采用确定性的方式将输入数据转化为哈希值。这意味着相同的输入数据将始终生成相同的哈希值。 -
哈希算法通常是单向的,即从哈希值无法还原出原始数据。这是由于哈希值通常比原始数据短,因此信息的一部分丢失。
唯一性
哈希算法的目标是确保不同的输入数据生成不同的哈希值。然而,由于哈希值的长度是有限的,因此哈希冲突是不可避免的。哈希冲突是指不同的输入数据映射到相同的哈希值。
良好设计的哈希算法应该最小化哈希冲突的概率,但不一定能完全消除。
解决哈希冲突的方式
对于生成唯一ID的目的,必须考虑如何处理哈希冲突。一种方法是添加随机性,以减少冲突概率。另一种方法是使用唯一性索引来验证生成的ID是否已经存在。
常见的哈希算法
-
哈希算法广泛应用于密码学、数据完整性验证、数据检索、数据比对、数字签名、数据结构(如哈希表)、信息安全等领域。 -
在生成唯一ID的上下文中,哈希算法可用于创建标识符,以确保其在给定数据上是唯一的。
总结
在测试权限问题上,要充分了解资源ID的生成方式才能去判断是否能够进行越权测试。上面介绍了几种常见的唯一ID生成方式,在测试过程中要灵活判断资源ID所使用的算法。
原文始发于微信公众号(信安路漫漫):常见生成唯一资源ID的方式
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论