需要Base64和XOR运算

Base64 and XOR operation needed

我有一些 IV 值(一个 URL 编码的 base64 字符串):

iv = "L9CsUSgEvjM%3D"

现在我需要对其进行 base64 解码,然后仅将解码字符串的第一个元素异或到 'a''b'

喜欢

decoded_iv[0] ^ 'a' ^ 'b'

我需要把上面异或的结果和原来的iv[0].

我的任务是:

decoded_iv[0] = decoded_iv[0] ^ 'a' ^ 'b'

但是我下面的代码不起作用。

iv = urllib.parse.unquote("L9CsUSgEvjM%3D");

decoded_iv = base64.b64decode(iv)

print(decoded_iv)

decoded_iv = list(decoded_iv)

print(decoded_iv)

decoded_iv[0] = str(chr(ord('a')^ord('b')^decoded_iv[0]))

decoded_iv = "".join(decoded_iv)
print(decoded_iv)

这会打印:

[47, 208, 172, 81, 40, 4, 190, 51]
Traceback (most recent call last):
  File "exploit.py", line 24, in <module>
    decoded_iv = "".join(decoded_iv)
TypeError: sequence item 1: expected str instance, int found

您似乎找到了一些 Python 2 代码,但该解决方案并未转换为 Python 3。在 Python 2 中,数据将是一个字符串,不是 bytes 值。 list(stringvalue) 会产生一个字符列表,而不是像您在这里那样的整数列表。在 Python 2 中需要 ord()chr() 调用以在字符串中的字符与其二进制值(0 到 255 之间的整数)之间进行转换。

在 Python 3 中,您几乎不需要做那么多的工作,因为 bytes() 对象 已经 一个序列字节整数。 bytesvalue[0] 给你第一个字节的整数值:

>>> import urllib.parse, base64
>>> iv = base64.b64decode(urllib.parse.unquote("L9CsUSgEvjM%3D"))
>>> iv
b'/\xd0\xacQ(\x04\xbe3'
>>> iv[0]
47

剩下唯一要解决的问题就是如何赋值回iv[0];您不能使用 bytes() 值,因为该对象类型是不可变的。这与字符串的情况完全相同(这就是为什么 Python 2 代码从字符串转换为列表,然后使用 "".join() 从列表转换回字符串)。

相反,只需使用 bytearray(),此类型为您提供可变字节序列。现在,您直接对位置 0 处的整数值使用 ^

请注意,ASCII 字符的整数值 a 是 97,而 b 是 98;这些值永远不会改变并且 XOR 是可交流的(您可以按任何顺序使用参数),所以只需与 97 ^ 98 == 3:

进行异或
iv = base64.b64decode(urllib.parse.unquote("L9CsUSgEvjM%3D"))
mutable_iv = bytearray(iv)
mutable_iv[0] ^= 3  # 'a' ^ 'b' is 3

如果您需要考虑不同的字符,则使用更多 bytes() 对象并索引到这些对象以获得整数,例如像 mod1, mod2 = b'a', b'b'xor_mod = mod1[0] ^ mod2[0].

请注意,也没有必要将 bytesarray 值连接到字符串中,bytesarray() 值可以在接受 bytes() 值的任何地方使用。例如。您可以将更新后的 IV 编码回 base64 和 URL-encoding:

>>> iv = base64.b64decode(urllib.parse.unquote("L9CsUSgEvjM%3D"))
>>> mutable_iv = bytearray(iv)
>>> mutable_iv[0] ^= 3  # 'a' ^ 'b' is 3
>>> mutable_iv
bytearray(b',\xd0\xacQ(\x04\xbe3')
>>> urllib.parse.quote(base64.b64encode(mutable_iv))
'LNCsUSgEvjM%3D'