前言
在一次测试过程中,发现了一处越权漏洞,其资源ID看起来是无序的,但是每个资源ID之间又有一点联系,因此就想去看看这种ID到底是否可以去预测。
查找了一些资料这些资源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。
数据量太大,我们通过爆破的方式去拿信息比较困难,而且容易被发现,当攻击成本超过了收益,那么也就没有什么意义了。因此雪花算法在一定程序上也保证了安全性。
雪花算法demo
import time
import threading
class SnowflakeGenerator:
def __init__(self, datacenter_id, worker_id):
self.datacenter_id = datacenter_id
self.worker_id = worker_id
self.sequence = 0
self.last_timestamp = -1
# Bit lengths for different parts
self.datacenter_id_bits = 5
self.worker_id_bits = 5
self.sequence_bits = 12
# Maximum values
self.max_datacenter_id = -1 ^ (-1 << self.datacenter_id_bits)
self.max_worker_id = -1 ^ (-1 << self.worker_id_bits)
self.max_sequence = -1 ^ (-1 << self.sequence_bits)
# Shift amounts
self.worker_id_shift = self.sequence_bits
self.datacenter_id_shift = self.sequence_bits + self.worker_id_bits
self.timestamp_shift = self.sequence_bits + self.worker_id_bits + self.datacenter_id_bits
self.lock = threading.Lock()
def _current_milliseconds(self):
return int(time.time() * 1000)
def _til_next_millis(self, last_timestamp):
timestamp = self._current_milliseconds()
while timestamp <= last_timestamp:
timestamp = self._current_milliseconds()
return timestamp
def generate_id(self):
with self.lock:
timestamp = self._current_milliseconds()
if timestamp < self.last_timestamp:
raise ValueError("Clock moved backwards. Refusing to generate id.")
if timestamp == self.last_timestamp:
self.sequence = (self.sequence + 1) & self.max_sequence
if self.sequence == 0:
timestamp = self._til_next_millis(self.last_timestamp)
else:
self.sequence = 0
self.last_timestamp = timestamp
return ((timestamp - 1288834974657) << self.timestamp_shift) |
(self.datacenter_id << self.datacenter_id_shift) |
(self.worker_id << self.worker_id_shift) |
self.sequence
def generate_unique_id(prefix: str, datacenter_id: int, worker_id: int) -> str:
generator = SnowflakeGenerator(datacenter_id, worker_id)
snowflake_id = generator.generate_id()
return f"{prefix}{snowflake_id}"
# 创建一个生成器,指定数据中心ID和工作机器ID
datacenter_id = 0
worker_id = 1
# 生成用户ID
user_id = generate_unique_id("USER_", datacenter_id, worker_id)
print(f"生成的用户ID: {user_id}")
原文始发于微信公众号(信安路漫漫):利用雪花算法生成的资源ID是否可以预测
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论