我试图演示一个简单的概念证明,即用C编写的游戏中的一段代码中的漏洞。
假设我们要验证字符登录。登录由用户从图形菜单中选择n
项(我们现在假设n=5
)来处理。这些物品都是中世纪主题:
例如:
_______________________________
| | | |
| Bow | Sword | Staff |
|-----------|-----------|-------|
| Shield | Potion | Gold |
|___________|___________|_______|
用户必须单击每个项目,然后为每个项目选择一个数字。
然后,验证算法执行以下操作:
- 确定选择了哪些项目
- 将每个字符串删除为小写(即:
Bow
变为bow
等) - 计算每个字符串的简单字符串哈希(即:'bow => b=2, o=15, w=23, sum = (2+15+23=40)
- 将哈希乘以用户为相应项目选择的值;此新值称为
key
- 将每个选定项的
keys
相加;这是最终的验证哈希 - 重要提示:验证者将接受此哈希值及其非零倍数(即:如果最终哈希值等于 1111,则 2222、3333、8888 等也有效)。
因此,例如,假设我选择:
Bow (1)
Sword (2)
Staff (10)
Shield (1)
Potion (6)
该算法将这些字符串中的每一个都变为小写,计算它们的字符串哈希,将该哈希乘以为每个字符串选择的数字,然后将这些键相加。
例如:
Final_Validation_Hash = 1*HASH(Bow) + 2*HASH(Sword) + 10*HASH(Staff) + 1*HASH(Shield) + 6*HASH(Potion)
通过应用欧拉方法,我计划证明这些哈希不是唯一的,并希望设计一个简单的应用程序来证明它。
就我而言,对于 5 个项目,我基本上会尝试计算:
(B)(y) = (A_1)(x_1) + (A_2)(x_2) + (A_3)(x_3) + (A_4)(x_4) + (A_5)(x_5)
哪里:
B is arbitrary
A_j are the selected coefficients/values for each string/category
x_j are the hash values for each string/category
y is the final validation hash (eg: 1111 above)
B,y,A_j,x_j are all discrete-valued, positive, and non-zero (ie: natural numbers)
有人可以帮助我解决这个问题或指出我一个类似的例子(即:代码、计算方程等)吗?我只需要解决最后一步(即:(B)(Y) = ...)。
最后,我编写了一个递归算法,该算法深入n
级别,然后处理所有剩余可能组合的增量、测试等。效率不是很高,但它有效。我可以根据要求提供(太大而无法在此处发布)。
,大多数用户会为每个项目选择相当小的数字(毕竟"2"比"438483"更容易记住)。
鉴于这种约束,蛮力实际上可能是合理的。
只需为 5 个符号加上一个数字(例如 1..99)生成所有可能的输入值,计算结果哈希值,并计算(例如使用字典)产生给定哈希的不同组合的数量,应该可以对最可能的输入值的哈希分布进行经验理解。
从那里,我将查看实际生成了多少个不同的哈希值(如果哈希是 Int32,则在 2^32 个可能的哈希值中),并查找以特定频率生成的哈希值(在字典中计数很高)。
它可能是唯一的,也可能不是唯一的,这取决于菜单上的项目x_j
、系数A_j
、验证哈希y
,以及n
选择的项目的数量。
例如,如果验证哈希1
,会发生什么情况?然后一切都会验证。
另一方面,如果您必须n
项目总数,那么只有一个可能的哈希是唯一的。
当然,这些都是极端的例子,但它们说明了这一点。这取决于您的参数。除了暴力破解之外,没有一个简单的通用方法来检测哈希是否唯一。
这很简单,因为该算法接受非零倍数。如果将所有输入乘以 2,则会出现冲突:
Bow (1)
Sword (2)
Staff (10)
Shield (1)
Potion (6)
y = (A_1)(x_1) + (A_2)(x_2) + (A_3)(x_3) + (A_4)(x_4) + (A_5)(x_5)
然后将它们乘以 2:
Bow (2)
Sword (4)
Staff (20)
Shield (2)
Potion (12)
2(A_1)(x_1) + 2(A_2)(x_2) + 2(A_3)(x_3) + 2(A_4)(x_4) + 2(A_5)(x_5)
= 2((A_1)(x_1) + (A_2)(x_2) + (A_3)(x_3) + (A_4)(x_4) + (A_5)(x_5))
= 2y
虽然这不是一个正式的证明,但我有一个想法。
让不同字符串的哈希值h_1
、h_2
、...,h_n
线性和为
y = h_1 + h_2 + ... + h_n
一旦我们有了y
,我们总能找到h_1'
,h_2'
,...,h_n'
,至少对于系列中的一对i
和j
h_i != h_j'
。
因此,我们可以有重复的h
值来获得最终总和。
同样,由于每个h
值都是由一些整数(字符的代表性值)的线性和生成的,因此可以通过不同的线性和(即不同的字符串)来实现特定的h
值。
数值可以调整。此外,即使乘数值是常数,即重复哈希生成器无法选择它,也可以修改乘以乘数的h
值,以使乘法键的总和保持不变。
因此,我们可以从许多字符串中生成一个哈希。
将除最后一个系数之外的所有系数设置为 1,因此您可以获得 An*xn = r (mod y) 的形式,然后使用扩展的欧几里得算法找到解决方案,请参阅维基百科