不可逆加密算法-MD5

前言

加密算法,根据是否可逆计算出明文,分为可逆加密算法与不可逆加密算法。

这两种类型的加密算法,在网络数据请求中广泛应用,提高网络安全性。其中的可逆加密算法用于加密数据包,保证数据安全,不可逆加密算法用于签名,防止数据篡改。这篇文章介绍不可逆加密算法中的md5,以及其应用场景。

MD5

md5信息摘要算法,一种被广泛应用的密码散列函数,根据数据产生一个128位的散列值。

md5算法具有以下特点:

  • md5值长度一致,不管数据量的大小,其产生的md5长度一致。
  • 数据的一个小更改,生成的md5就会不一样,可以有效的防止数据篡改

长度一致性

s = "fdasfffffffffffasfsdddddddddddddddddddddddddddddddd"
print(hashlib.md5(s.encode("utf-8")).hexdigest())
print(hashlib.md5('11'.encode("utf-8")).hexdigest())

#输出
7b7e575bd10c3fdab6b7b6e306f2daef
6512bd43d9caa6e02c990b0a82652dca

如上案例,不管是一个长度为2的数据还是长度为51的数据,通过md5计算出来的值长度都是一个128位的值。就算数据再大,通过md5计算出来,其md5的长度都会是128位。

备注:

这里输出的md5字符串长度为32,16进制,每一个字符4位,共计128位。

数据安全性

s = "1" + "qqwertyusdfghxcvbnmikmuj" * 10000
print(hashlib.md5(s.encode("utf-8")).hexdigest())
s = "2" + "qqwertyusdfghxcvbnmikmuj" * 10000
print(hashlib.md5(s.encode("utf-8")).hexdigest())

#输出
0afc01e49fb2fb4041016874c23560cf
219ba5b3171553274c40c038bd3ca9bb

上面案例,两次计算md5值的数据,24W+1个字符串中,只有第一个字符串是不一样的,但是从计算出来的md5值来看,两者的md5值完全不一样。可见md5算法是可以有效的防止数据篡改的。

应用场景

不可逆的加密算法,广泛应用于网络请求和密码保存的场景下。

密码保存

每一个系统,都不可避免的需要保存用户的密码信息,只有保存了密码信息才能在用户登录时,对其用户名密码进行校验,来完成认证。但是在数据库中明文保存密码是一大忌,为什么呢?下面简单举出两个例子说明一下:

1)2011年12月,CSDN网站备份数据库遭黑客攻击,600万用户的登录名、密码数据被窃取,之后天涯、世纪佳缘、走秀等多家网站的用户数据库也在网上被曝光。

2)2017年11月,媒体发布消息称,趣店百万学生的数据疑似外泄,泄露的数据出包括借款金额、滞纳金等金融数据外,甚至还包括学生父母电话、男女朋友电话、学信网账号密码等隐私信息。据称,此次数据泄露事件有可能是内鬼所为,内部人员主动泄露这些数据以进行报复。

所以利用不可逆的加密算法保存密码信息,可以有效的保护用户的数据安全。虽然现在大部分的系统都不再保存明文密码了,但是我们在平常的生活中,还是可以提高下面的做法来进一步提高自己的信息安全:

  • 密码复杂度,不要太低。防止通过密码本暴力破解
  • 不要所有系统设置相同密码,防止撞库现象的发生(黑客通过收集互联网已泄露的用户和密码信息,生成对应的字典表,尝试批量登陆其他网站后,得到一系列可以登录的用户)

数据签名

为了防止网络请求,被恶意修改。为了验证消息体的合法性,很多系统都使用不可逆算法来进行消息体签名。客户端发送网络请求时,根据约定的机制,通过不可逆算法生成消息体的签名,并将计算的值放入消息体中,一并发送给服务端。服务端获取到消息体之后,可用以验证消息体的真实性。

常见的消息体签名:

# md5
def signature(parameters):
    sorted_parameters = sorted(parameters.items(), key=lambda parameters: parameters[0])
    query_string = ''
    for (k, v) in sorted_parameters:
        query_string += k + "=" + str(v) + "&"
    query_string = query_string[:-1]
    return hashlib.md5(query_string.encode("utf-8")).hexdigest()

print(signature({
    "name": "test",
    "password": "tteesst"
}))

如上图,通过将消息体排序之后,拼接的方式再进行不可逆加密计算的方式,获取到消息体的签名。然后在发往服务端的数据中,除了原有的消息体之外,还需要携带签名值。服务端会通过相同的方式,去计算消息体的签名,并与客户端发送的签名值进行匹配,如果匹配不通过的话,将视为消息体被篡改。

posted @ 2022-09-15 15:35  红雨520  阅读(135)  评论(0编辑  收藏  举报