nss:404(RC4)
oh~~shit
我们在之前做过这种类型的题,RC4,在线网站一解ok,我试试看看行不行
不对....那我们认真看代码吧
导入模块
urllib.parse 是 Python 标准库 urllib 模块中的一个子模块,用于处理 URL 的解析和构建。它提供了一些有用的函数来拆解(parse)和组合(build)URL,可以帮助你轻松地处理与 URL 相关的操作。
base64,我们都学过了
解题前奏
看到256,我觉得我们应该认真看一下RC4教学,因为我RC4理解的不是很好,所以现在需要重新复习一下
那我们也应该去学习一下,rc4的解密,之后才能解出这个题。在学习rc4解密的时候,我们应该去看一下c语言脚本,然后试着自己写一下c语言的。如果写出来,我们肯定就是理解了。 (当然我的c语言base64还不会----捂脸)(这个题写出来,自己试着写一下)
这个视频和上面的视频结合着看,便于理解
rc4原理
RC4算法是一种流加密算法,其基本原理包括初始化和伪随机子密码生成算法。
RC4算法的基本原理
RC4算法的核心在于生成一个伪随机数序列,该序列用于对明文进行加密。算法的主要步骤如下:
-
初始化:算法使用一个256字节的状态向量S,初始时S的每个元素值为0到255的整数。
-
密钥调度算法(KSA):使用输入的密钥K,通过KSA将密钥K与状态向量S混合,生成一个新的Sbox。
-
伪随机数生成算法(PRGA):通过PRGA生成密钥流,该密钥流与明文进行异或运算,生成密文。
RC4算法的具体步骤
-
初始化状态向量S:S是一个长度为256的数组,初始时所有元素值为0。
-
密钥调度算法(KSA):
-
将密钥K与S混合,生成新的Sbox。混合过程如下:
-
初始化两个指针i和j,i和j的初始值为0。
-
对每个元素s[i],计算i=(i+1)%256,j=(j+s[i]+key[i % strlen((char *)key))%256,然后将s[i]和s[j]交换。
-
重复上述过程,直到整个Sbox被混合。
-
-
-
伪随机数生成算法(PRGA)
:
-
初始化两个指针i和j,i和j的初始值为0。
-
对每个需要加密的字节,计算i=(i+1)%256,j=(j+s[i])%256,然后计算t=(s[i]+s[j])%256。
-
生成密钥流字节为s[t]。
-
将密钥流字节与明文字节进行异或运算,生成密文字节。
自我感受
这个题,在我看了之后,他肯定是以rc4为基础的。为底子的。我们接下来继续。
-
代码部分
我们通过学习导入模块的了解,看到最后面enc = urllib.parse.quote(enc),说明这个可能是一个URL加密,我们百度一下这个函数。
urllib.parse.quote(enc) 是 Python 中 urllib.parse 模块的一个函数,用于对字符串 enc 进行 URL 编码。URL 编码(也称为百分号编码)是一种将字符串转换为合法的 URL 组件的方法,特别是用于处理 URL 中可能存在的特殊字符或非 ASCII 字符。
我们进入在线网站看一下将我们要解密的enc放入url解码后得到:¦nYg? 1.÷ÊÀWÌú (我有点怀疑,我们还是从头开始看吧。。。)
一.初始化s表
s_box = list(range(256))
很显然这个就是rc4前面设定一个s表,不需要初始化,因为在 Python 中的作用是创建一个包含从 0 到 255(包括 255)整数的列表。具体来说:
-
range(256)会生成一个从 0 到 255 的数字序列。 -
list()会将这个序列转换成一个列表。
执行完这行代码后,s_box 列表的内容将是:
python [0, 1, 2, 3, 4, 5, 6, 7, ..., 255]
二.KSA,生成新的S_BOX
for i in range(256): j = (j + s_box[i] + ord(key[i % len(key)])) % 256 s_box[i], s_box[j] = s_box[j], s_box[i]
三.伪随机数生成算法(PRGA)
i = j = 0 for s in flag: i = (i + 1) % 256 j = (j + s_box[i]) % 256 s_box[i], s_box[j] = s_box[j], s_box[i] t = (s_box[i] + s_box[j]) % 256 k = s_box[t] res.append(chr(ord(s) ^ k))
四.其余代码解释:
1.(.join)
cipher = "".join(res)
的作用是将 res 列表中的所有元素连接成一个字符串,并将结果赋值给变量 cipher。具体来说:
-
res是一个包含多个元素(通常是字符串或字符)的列表。 -
"".join(res)会将res列表中的每个元素连接成一个单一的字符串,元素之间没有任何分隔符(因为连接字符串时分隔符是空字符串"")。
假设 res 列表是这样的:
python res = ['h', 'e', 'l', 'l', 'o']
执行 cipher = "".join(res) 后,cipher 的值将是:
python cipher = "hello"
2.
crypt = (str(base64.b64encode(cipher.encode('utf-8')), 'utf-8'))
enc = str(base64.b64decode(crypt),'utf-8')
enc = urllib.parse.quote(enc)
这部分很好理解,跟我们之前学的base64加解密一样,只不过最后将base64加密结果变成了URL编码,所以我们需要再次用base64解密,但是他好像又解密了......
解题思路
我们首先需要先将我们要解密的enc从URL编码转换一下:
enc = '%C2%A6n%C2%87Y%1Ag%3F%C2%A01.%C2%9C%C3%B7%C3%8A%02%C3%80%C2%92W%C3%8C%C3%BA' enc = urllib.parse.unquote(enc)
但是解码后,和上面一样,很显然不正确呀,URL解码后是:¦nYg? 1.÷ÊÀWÌú 。这时候我们想一想。我之前编写base64的时候,因为他最开始是字符串。在我们使用enc.encode()变成一个个字节。那在这个题当中,他最后使用base64,并没有使用enc.decode使他变回字符串。所以在题目中使用URL编码,编码的是enc是字节的结果,而不是字符串。 注意:我这段话是废话,因为不影响
这样我们写个例子吧
但是,我目前还有一个想法就是出现这种状况,我们知道我们平常都是使用ascll码的base64也是只是用ascll码,但是前面内容是ord使用的是Unicode,所以应该并不冲突。那问题到底出在哪呢???????????
我现在在原题中,在cipher = "".join(res)后面加入print(res)和print(cipher)
而
res:['\x90', 'E', '¬', 'b', '6', 'Y', '<', '\x8a', '\x0c', '\x17', '¨', 'Ð', '÷', ' ', 'ç', '¸', 'l', '\x80', 'ÿ']
cipher:E¬b6Y<¨Ð÷ ç¸lÿ
这超出ascll码的范围了我靠
我们还是试着写一下rc4解密吧(我们的目的是算出t)-----经过好多尝试,这个转换的地方就有问题,但我又不知道哪里出了问题,先搁置一下
关于rc4解密,基本和加密都是一样的步骤,而不一样的步骤在于下面的for s in enc这一步
后面基本都一样

465

被折叠的 条评论
为什么被折叠?



