我想用 KEY 对字符串(实际上是它的二进制表示形式)进行按位异或。
运算结果应以十六进制表示。
我有: 'a' - 要更改的 UTF-8 字符串。 'ACF123456' - 十六进制密钥。
结果显示为 BIGINT:
select CONV(HEX('a'), 16, 10) ^ CONV('ACF123456', 16, 10);
结果显示为十六进制:
select CONV( CONV(HEX('a'), 16, 10) ^ CONV('ACF123456', 16, 10), 10, 16);
问题:
谢谢。
CONV()
和 ^
确实具有 64 位精度。
2^64 = 16^16,因此超过 16 个十六进制数字的字符串应该转换为大于 2^64 的整数。然而,当尝试将这些字符串转换为整数时,这些字符串将被残酷地(无声地)从左侧截断。
我的解决方案的要点是对这些字符串进行切片。显然,结果可能不会显示为整数,而只能显示为字符串表示形式。
让
@input
成为您的“要更改的字符串”,@key
,您的“密钥”。
HEX(@input)
分配给 @hex_input
。这里没问题,因为 HEX()
适用于字符串。@hex_input
切成 16 个十六进制数字长字符串,从右侧开始@key
切成 16 位长的字符串。X-OR
的每个 64 位切片计算 @hex_input
的每个 64 位切片的 @key
。使用CONV(@slice, 16, 10)
。如果 @hex_input
或 @key
的切片少于另一个字符串,则 X-OR
另一个字符串的剩余切片为 0。X-OR
.将第 4 点中的
UNHEX()
三列
TEMPORARY
表可以用作数组来存储 @hex_input
、@mask
的切片以及生成的切片。
将所有这些放在一个存储过程中,然后voilà!
听起来你对MySQL有一些技能,你应该能够将上面的内容翻译成真正的代码。但如果您需要进一步的指导,我很乐意提供帮助。
上面的转换是否正确?
不,操作数的大小不同,如果字符串的大小已知,则您已将密钥的其余部分提供给了可能的攻击者。
select HEX(CONV(HEX('a'), 16, 10) ^ CONV('ACF123456', 16, 10));
返回:
'ACF123437'
部分密钥清晰地出现在输出中:
'ACF1234'
其余:
HEX(HEX('a') ^ 0x56)
返回:
'37'
如果密钥仅使用一次(一次垫)或数据是固定大小的字符串或(非重复密钥长度等于或大于可能的数据并且知道数据的长度不是问题。)那么这种解决方案就可以了。
但是如果将相同的键应用于具有可变长度数据的整个列,则可以应用统计分析,从而大大减少搜索空间,特别是如果该人之前对数据有任何了解的话。
适用于任何字符串的任何解决方案:
从 MySql 8 开始,但从 11.3 开始不包括 MariaDB,您可以在
&
上使用按位 AND OR XOR NOT(分别为|
,^
,~
,BINARY()
)运算符。产生大于 64 位结果的数据类型。
操作数的大小必须相同。石膏将 0 垫以填补尺寸差异。
必须注意确保数据和密钥的大小相同,因为任何长度差异都将输出原始数据或密钥,因为任何与 0 异或的值都会给出原始数据。上面表达了担忧。
select CAST('a' as BINARY(1)) ^ CAST(0xACF123456 as BINARY(1));
返回包含 0xCD 的
BINARY(1)
:0x61 ^ 0xAC
请注意截断的顺序,
AC
而不是56
,这可能与其他语言、平台或之前用法(即发布的代码)的预期结果不匹配。如果需要兼容性,请反转字节顺序(0x563412CF0A)。
您可以
HEX
结果:
select HEX(CAST('Hello World!' as BINARY(12)) ^ CAST(0xACF123456ACF123456ACF123 as BINARY(12)));
'E4944F2905EF455B24C09502'
反转(注意上面字符串中添加的
0x
):
select CAST(CAST(0xE4944F2905EF455B24C09502 as BINARY(12)) ^ CAST(0xACF123456ACF123456ACF123 as BINARY(12)) as CHAR(12));
“世界你好!”
BINARY(n)
大小n
表示为字节数,因此数据和密钥必须对齐为8位。 ACF123456
的非对齐键需要变为 ACF1234560
或 0ACF123456
才能满足对齐要求。
注意:上述字节反转的实现由“0x563412CF0A”中的“0A”给出。
此解决方案对于已知长度的字符串或动态生成的 SQL 语句有效,因为传递给
size
的 Binary(size)
不能是函数或参数。