自学内容网 自学内容网

[Python学习日记-51] Python 中的加密模块 —— hashlib

[Python学习日记-51] Python 中的加密模块 —— hashlib

简介

HASH

MD5

SHA-1

MD5 与 SHA-1的比较

hashlib 模块

简介

        在这个信息时代,互联网越来越发达,越来越多的东西都开始信息化了,甚至有的人已经很久都没有使用过现金了,一直都是使用电子支付,而在交易时肯定需要进行网络传输,而在这中间很容易就会受到黑客的攻击,你的信息就会泄露,更严重的还会造成经济损失,所以为了保护好这些重要的数据,那一定要在传输前对这些数据进行加密。而在 Python 中比较常用的就是 hashlib 模块进行加密,而这个模块的加密算法都是基于 HASH 算法的,所以我们先了解一下,什么是 HASH 吧。

HASH

        Hash,一般翻译为“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射 —— pre-image)通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
        HASH 主要用于信息安全领域中加密算法,他把一些不同长度的信息转化成杂乱的128位的编码里,而这个杂乱的128位的编码被称为 HASH 值。也可以说,HASH 就是找到一种数据内容和数据存放地址之间的映射关系。

MD5

一、什么是 MD5 算法

        MD5 讯息摘要演算法(MD5 Massage-Digest Algorithm),它是一种被广泛使用的密码杂凑函数,可以产生出一个128位的散列值(hash value),用于确保信息传输完整一致。而 MD5 的前身有 MD2、MD3 和 MD4,其前身目前已经淘汰,基本没在用了。

二、功能

        将输入任意长度的信息经过算法处理,输出为128位的信息(数字指纹),并且不同的输入得到的是不同的结果,两个相似的输入经过算法运算后会得出完全不一样的输出结果,并且具有唯一性。

三、特点

  1. 压缩性:任意长度的数据,算出的 MD5 值的长度都是固定的
  2. 容易计算:从原数据可以很容易计算出 MD5 值
  3. 抗修改性:对原数据进行任何改动,修改一个字节生成的 MD5 值区别也会很大
  4. 强抗碰撞:已知原数据和使用的是 MD5 算法的情况下,想找到一个具有相同 MD5 值的数据,即伪造数据,是非常困难的

四、MD5 算法是否可逆

        MD5 不可逆的原因是其是一种散列函数,使用的是 HASH 算法,这是因为在计算过程中原文的部分信息是被丢弃了的。

五、用途

1、防止被篡改

        比如发送一个电子文档,发送前我先运行 MD5 算法得到输出结果为 A。然后在对方收到电子文档后,对方运行 MD5 算法得到一个输出输出结果为 B。放在一起进行比较,如果 A 与 B 一致就代表中途未被篡改。

        例如我开发了一个程序,放在软件网站上供大家下载使用,为了防止不法分子在安装程序中添加木马,我可以在网站上公布由安装文件经过 MD5 算法运算后输出的结果(MD5 值),下载者下载文件后把下载的安装文件进行 MD5 算法运算后得到的结果如果和我公布的不一致就代表被人动过,可能会存在风险。

        而 SVN(开放源代码的版本控制系统 —— Subversion)在检测文件是否在 CheckOut 后被修改过,也是用到了MD5 算法

2、防止明文显示

        现在很多网站在数据库存储用户密码的时候都是存储用户密码的 MD5 值。这样就算不法分子得到数据库的用户密码的 MD5 值,也无法知道用户的密码。例如在 Unix 系统中用户的密码就是以 MD5 或者其它类似的算法,经过加密后存储在文件系统中。当用户登录的时候,系统把用户输入的密码计算成 MD5 值,然后再去和保存在文件系统中的MD5值进行比较,进而确定输入的密码是否正确。通过这样的步骤,系统在并不知道用户密码明文的情况下就可以确定用户登录系统的合法性。这不但可以避免用户的密码被具有系统管理员权限的用户知道,而且还在一定程度上增加了密码被破解的难度。

        但是随着计算机技术的发展,计算机性能越来越强打了,了解 MD5 算法运行规则也研究得越来越深入了,但由于 MD5 的不可逆性还是无法从 MD5 值下手进行破解,所以不法分子采取了另辟蹊径的手法,那就是撞库,即利用穷举法进行对 MD5 值的匹配,这就是利用了 MD5 的防篡改功能,但是这一做法需要先获得存在数据库当中的用户密码的 MD5 值先(而这一步就叫做脱库,就是我们时不时会听到某某公司被脱库,指得就是这些),然后进行撞库。这个撞库过程需要消耗的计算资源和时间取决于你密码的复杂程度,所以这就是为什么平时创建账号时对你的密码的复杂度都是有要求的。但是这样撞库,撞中只是时间问题而已,所以为了进一步的加强安全性,通常都会在 MD5 值的基础上加上一段字符,然后再通过自己开发的算法进行加密,而这种做法被称为加盐。

        这样就算不法分子花再多的时间撞库出来的明文数据都不会是用户的密码,这样进一步保障了用户密码的安全性。

3、防止抵赖(数字签名)

        数字签名需要一个第三方认证机构,即证书颁发机构(CA, Certificate Authority)。例如 A 写了一个文件,认证机构对此文件用 MD5 算法产生摘要信息并做好记录。若以后 A 说这文件不是他写的,权威机构只需对此文件重新产生摘要信息,然后跟记录在册的摘要信息进行比对,相同的话,就证明是 A 写的了。这就是所谓的“数字签名”。

SHA-1

        安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard Dss)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于2^64位的消息,SHA-1 会产生一个160位的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。
        SHA是美国国家安全局设计的,由美国国家标准和技术研究院发布的一系列密码散列函数。由于 MD5 和 SHA-1 于2005年被山东大学的教授王小云破解了,科学家们又推出了 SHA-224,SHA-256,SHA-384,SHA-512,这些算法并没有太大的变化,而是使用更长的位数来加大破解难度,所以位数越长破解难度就会越大,但同时生成加密的消息摘要所耗时间也更长。目前最流行的是加密算法是 SHA-256。

        SHA 与 MD5 同属于哈希加密算法,他们在功能、特点、用途上是极为相似的,所以这里也不过多赘述了。

MD5 与 SHA-1的比较

        由于 MD5 与 SHA-1 均是从 MD4 发展而来,它们的结构和强度等特性有很多相似之处,SHA-1 与 MD5 的最大区别在于其摘要比 MD5 摘要长32比特。

        对于强行攻击,产生任何一个报文使之摘要等于给定报文摘要的难度:MD5 的 2^128 数量级的操作,SHA-1 是 2^160 数量级的操作;产生具有相同摘要的两个报文的难度:MD5 是 2^64 数量级的操作,SHA-1 是 2^80 数量级的操作。因而,SHA-1 对爆破攻击的强度更大。但由于 SHA-1 的循环步骤比 MD5 多(80比64)且要处理的缓存大(160bit 比 128bit),所以 SHA-1 的运行速度比 MD5 慢。

hashlib 模块

        用于加密相关的操作,Python3 里用 hashlib 代替了Python2 中的 md5 模块和 sha 模块,主要提供 SHA-1、SHA-224、SHA-256、SHA-384、SHA-512、MD5 算法。使用方法如下

一、MD5

import hashlib

# 单次update
m = hashlib.md5()
m.update(b"Hello")    # hashlib 只能接收字节,纯英文的可以直接在前面加 b 来把字符串字节化

print("二进制的hash值:",m.digest())    # 返回二进制格式的 hash 值
print("十六进制的hash值:",m.hexdigest())    # 返回十六进制格式的 hash 值

# 多次update
m1 = hashlib.md5()
m2 = hashlib.md5()
m1.update(b"Hello")
m1.update(b"It's me")
m2.update(b"HelloIt's me")
print("分开两次update的hash值:",m1.hexdigest())    # 分开两次update其实和两个字符串拼接在一起然后hash的值是一样的
print("两个字符串拼在一起update的hash值",m2.hexdigest())

# 无论多长的字符串最终都会只输出固定长度的hash值
m3 = hashlib.md5()
m3.update(b"It's been a long time since last time we ...")
print("长字符串的hash值:",m3.hexdigest())

# 含有中文字符的字符串
m4 = hashlib.md5()
str = "祝你早上好,中午好,下午好,快乐每一天!——《楚门的世界》".encode("utf-8")
m4.update(str)
print("含有中文字符的字符串的hash值:",m4.hexdigest())

代码输出如下:

二、SHA

import hashlib

str = "祝你早上好,中午好,下午好,快乐每一天!——《楚门的世界》"

# sha-1
s1 = hashlib.sha1()
s1.update(str.encode("utf-8"))
print("sha-1:",s1.hexdigest())

# sha-256
s256 = hashlib.sha256()
s256.update(str.encode("utf-8"))
print("sha-256:",s256.hexdigest())

# sha-512
s512 = hashlib.sha512()
s512.update(str.encode("utf-8"))
print("sha-512:",s512.hexdigest())

# sha-256 多次update
s2 = hashlib.sha256()
s3 = hashlib.sha256()
s2.update(b"Hello")
s2.update(b"It's me")
s3.update(b"HelloIt's me")
print("分开两次update的hash值:",s2.hexdigest())    # 分开两次update其实和两个字符串拼接在一起然后hash的值是一样的
print("两个字符串拼在一起update的hash值",s3.hexdigest())

代码输出如下:


        其实本次借着介绍 Python 中的 hashlib 模块简单介绍了密码学当中的两种加密算法:MD5 和 SHA,其实密码学非常奇妙,并且有些地方非常巧妙,就跟德国机械制造一样,如果你也想和我一起探讨密码学的奥秘的话,请在评论区留言或直接私信我与我交流。 


原文地址:https://blog.csdn.net/zjw529507929/article/details/142978377

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!