JavaScript逆向之md5算法

md5算法

md5算法简介:md5算法是一种摘要算法,主要用来进行数字签名、文档一致性验证等。

python实现md5

点击查看代码
from hashlib import md5
s="123456"
obj = md5()
# 把你要计算的字节丢进去
obj.update(s.encode("utf-8"))
md5_value = obj.hexdigest()     
print(md5_value)  # e10adc3949ba59abbe56e057f20f883e
如果想把计算md5值作为一个方法进行封装,需要考虑以下两种封装方式: (1)第一种,创建md5算法的声明变量在方法之外
点击查看代码
from hashlib import md5

obj = md5()
def func(s):
    obj.update(s.encode("utf-8"))
    md5_value = obj.hexdigest()     # 第一次是"樵夫"的md5值,第二次是"樵夫樵夫"的md5值
    print(md5_value)

func("123456")  # e10adc3949ba59abbe56e057f20f883e
func("123456")  # ea48576f30be1669971699c09ad05c94
可以看到这种声明方式,计算"123456"的md5值的结果都不一样,这是为什么呢?因为md5算法的声明变量在方法之外,每次调用func函数计算md5值的时候用的都是同一个变量,第一次调用func函数计算的确实是"123456"的md5值,而第二次调用func函数计算的就是"123456123456"的md5值了,所以这种方法不可取。 (2)第二种,创建md5算法的声明变量在方法内
点击查看代码
from hashlib import md5

def func(s):
    obj = md5()
    # 把你要计算的字节丢进去
    obj.update(s.encode("utf-8"))
    md5_value = obj.hexdigest()     # 第一次是"樵夫"的md5值,第二次是"樵夫樵夫"的md5值
    print(md5_value) 

func("123456")  # e10adc3949ba59abbe56e057f20f883e
func("123456")  # e10adc3949ba59abbe56e057f20f883e
这种才是正确的将计算md5值进行封装的写法。

md5算法加盐

MD5算法加盐其实就是在你想要加密的明文的前面或者后面加上一段字符串,是用来解决撞库问题的。
我们可以通过一段代码来验证。

点击查看代码
from hashlib import md5

obj1 = md5(b'1234')    # 设置盐
obj1.update('love'.encode("utf-8"))
md5_value1 = obj1.hexdigest()
print(md5_value1)    # f5939b22f92b4a71e39c0281764c36ed
obj2 = md5()
obj2.update('1234love'.encode("utf-8"))
md5_value2 = obj2.hexdigest()
print(md5_value2)    #f5939b22f92b4a71e39c0281764c36ed
从代码中可以看出,python实现加盐的原理是将盐加在我们想要加密的明文之前的。 其余的摘要算法,如sha1,sha256,sha512的用法与md5一致,都位于hashlib库下,只需要将其引入即可。

总结:如果在网站上看到一些加密逻辑,发现计算的结果是32位字符串,并且该字符串的组成是0-9a-f,可以大胆猜测是md5算法。然后尝试将123456传递进去,如果结果是e10开头的,那么他就是标准的md5算法,就可以直接写python代码了。但是如果计算的结果不是e10,那就有可能是魔改的md5算法了,这种就需要一步一步去抠代码。

有道翻译——md5逆向

为了能够加深印象,用有道翻译来实践一下。
url:https://fanyi.youdao.com/index.html#/
访问url地址,打开开发者工具,随便输入一个单词,看会触发哪些流量(还是只看Fetch/XHR的流量就可以了)。

查看每一条流量的payload。


这两条流量的payload都存在我们不能理解的参数,应该是被加密过了。接下来就是看其如何加密的,这里就以webtranslate/key这条流量为例进行操作。
寻找加密过程有两种方法,一个是看initiator,一个是搜索关键词,为了方便,这里就通过搜索关键词来定位。
那么如何来选取关键词呢,第一种就是通过搜索url中的关键词,第二种这里还可以搜索参数关键词,例如sign和mysticTime。这里就通过搜索url关键词了。

找到一条记录。

打上断点。可以看到该行后面有许多小箭头,这些箭头是说明这一行代码这些代码都可以打断点,为了能够参数是什么,所以需要在离参数比较近的地方打断点。

通过快捷键ctrl+shift+r来刷新界面。

经过一个一个变量的查看,都没有看到payload中的关键词,最后定位在了E函数上面,跳转到声明E函数的地方。

E函数中明显出现了sign、mysticTime等关键词,在函数的第三行打上断点,跳转到E函数内。

变量o就是获取当前时间戳,再将变量o赋值给mysticTime,所以mysticTime其实就是时间戳。下面主要来看sign是如何生成的,sign=k(o,e),看下k函数是如何实现的。

k函数调用了j函数,再看j函数如何实现。

j函数是用来生成md5值的。那其实就是k函数将模板字符串传递给j函数,生成md5值后赋值给sign。看下模板字符串的组成。
client=${u}&mysticTime=${e}&product=${d}&key=${t}
四个参数,client、mysticTime、product、key,其中client,product,key三个是定值,mysticTime是时间戳。

直到了如何计算md5值,python代码就很好写了。

点击查看代码
import requests
from hashlib import md5
import time

t = int(time.time() * 1000)  # 获取时间戳
obj = md5()
obj.update(f"client=fanyideskweb&mysticTime={t}&product=webfanyi&key=asdjnjfenknafdfsdfsd".encode("utf-8"))
sign = obj.hexdigest()
params = {
    "keyid": "webfanyi-key-getter",
    "sign": sign,
    "client": "fanyideskweb",
    "product": "webfanyi",
    "appVersion": "1.0.0",
    "vendor": "web",
    "pointParam": "client,mysticTime,product",
    "mysticTime": t,
    "keyfrom": "fanyi.web"}
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 "
                  "Safari/537.36",
    "Referer": "https://fanyi.youdao.com/",
    "Cookie": "xxxxxx",
}

resp = requests.get("https://dict.youdao.com/webtranslate/key", headers=headers, params=params)
print(resp.text)

这样即可取得数据。

posted @ 2024-03-05 11:51  死不悔改奇男子  阅读(372)  评论(0编辑  收藏  举报