安全哈希和信息摘要算法--Python3中的hashlib

需求是为了生成数据的‘指纹信息’,通过指纹信息来确认数据是否发生了改变。
通过md5.sha等数学方法去生成数据的指纹信息。
摘要算法又称为哈希算法、散列算法。把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)

这些算法都是单向的,因此能够知道数据是都是被篡改过的。任意长度的数据经过算法的处理后得到一个长度固定的字符串(又称为哈希值);但是通过哈希值并不能反推出数据。

注意: 哈希算法不是加密算法,正是因为它是单向的,不能通过哈希值反推出数据。
  1. 不管输入数据的数据量有多大,输入同一个哈希算法,得到的加密结果长度固定。
  2. 哈希算法确定,输入数据确定,输出数据能够保证不变
  3. 哈希算法确定,输入数据有变化,输出数据一定有变化,而且通常变化很大
  4. 哈希算法不可逆
    Git 底层采用的是 SHA-1 算法。

Python中的hashlib
  • Python的hashlib模块提供了很多安全哈希和信息摘要算法。
    信息摘要算法又被称为安全哈希,旧的算法被称为信息摘要,现代的算法术语称为安全哈希。

模块提供的哈希算法:SHA1, SHA224, SHA256, SHA384, SHA512,还有MD5。
模块为每种类型的hash提供了构造方法,构造方法产生的hash对象都具有相类似的接口:使用md5()创建一个MD-5 hash对象,通过对象的update对象方法,能够将数据(要求是bytes对象)提供给hash对象进行处理,然后通过hash对象的digest或者是hexdigest()方法获取哈希值。

>>> import hashlib
>>> md5 = hashlib.md5()
>>> md5.update(b'secure hashes and message digests')
>>> md5.hexdigest()
'3efd39afb56985b413d477baddf915f3'

其余的哈希算法的使用是一样的流程

>>> import hashlib
>>> sha256 = hashlib.sha256()
>>> sha256.update(b'secure hashes and message digests')
>>> sha256.hexdigest()
'c109ac280fc1de0041adb1f02af1be4a849895bb7b40b3c5a766d3e208e8d36b'

使用的时候有一些需要注意的点:

  1. 数据要求是bytes对象,也就是说在Python3中不能对普通的str类型的字符串进行处理,应转换为bytes对象。上面的例子中我们直接在普通字符串前加了一个‘b’ ,但是这种方式对字符集有要求不能转换中文字符,实际使用过程中,还有另外的两种能指定字符集的将str转为bytes的方式.

第一种方式:bytes("Python3 str==>bytes 指定编码格式", encoding='utf-8')
第二种方式:"Python3 str==>bytes 指定编码格式".encode('utf-8')

  1. hash对象的update()的用法,它支持将数据分块连续的进行update()。如果数据量很大我们就能像下面这样分块多次的调用update方法。最后得到的哈希值和一次性处理得到的哈希值是一样的。
>>> import hashlib
>>> md5 = hashlib.md5()
>>> md5.update('secure hashes'.encode('utf-8'))
>>> md5.update(' and '.encode('utf-8'))
>>> md5.update('message digests'.encode('utf-8'))
>>> md5.hexdigest()
'3efd39afb56985b413d477baddf915f3'

  1. 注意:如果是要比对两个数据的哈希值,必须要生成两个hash对象,不能使用一个对象进行持续的update,那样就违背了上面说到的update()的用法。

应用

安全哈希通常用来校验信息的一致性。

  1. Web中,用来产生token(标识用户的身份和权限)
  2. 现在大部分的网络部署和版本控制工具都在使用散列算法来保证文件可靠性。
  3. 在做开发时,经常会调用各大开放平台的API接口过程中,无一例外都会用到计算签名值(signature)。而在各种计算签名的方法中,经常被采用的就是HMAC-SHA1,现对HMAC-SHA1做一个简单的介绍:
import hmac
import hashlib
import base64
# secret_key:即接口的key
# data:要加密的数据
digest = hmac.new(secret_key,data,hashlib.sha1).digest().encode('base64').rstrip()

HMAC,散列消息鉴别码,基于密钥的Hash算法认证协议。 实现原理为:利用已经公开的Hash函数和私有的密钥,来生成固定长度的消息鉴别码;

BASE64,将任意序列的8字节字符转换为人眼无法直接识别的符号编码的一种方法;


不安全性

有没有可能两个不同的数据通过某个摘要算法得到了相同的摘要?完全有可能!

哈希碰撞(hash collision):不同的数据通过某个摘要算法得到了同一个哈希值

防止哈希碰撞的最有效方法是扩大哈希值的取值空间,但是更长的哈希值就意味着更大的存储空间和更多的计算,这会影响程序性能,增加成本。

根据实际的安全需求去评估自己需要的哈希值的长度:
思考一下下面的问题:(1.为什么考虑API请求碰撞的问题,怎么去计算碰撞出现的概率)
现在有一家公司,它的 API 每秒会收到100万个请求,每个请求都会生成一个哈希值,假定这个 API 会使用10年。那么,大约一共会计算300万亿次哈希。能够接受的哈希碰撞概率是1000亿分之一(即每天发生一次哈希碰撞),请问哈希字符串最少需要多少个字符?

一般来说,哈希值由大小写字母和阿拉伯数字构成,一共62个字符(10 + 26 + 26)。如果哈希值只有三个字符的长度(比如abc),取值空间就是 62 ^ 3 = 238,328,那么10000次计算导致的哈希碰撞概率是100%。

哈希碰撞与生日攻击

任何一种摘要算法都是存在发生碰撞的概率的,但即便是MD5这种已经过时的散列算法,也很难实现逆向运算。我们现在更多的还是依赖于海量字典来进行尝试,也就是通过已经知道的大量的文件和哈希值之间对应关系,搜索某个哈希值所对应的文件是否在数据库里存在。


参考资料:
hashlib — Secure hashes and message digests

python hashlib模块

hashlib-廖雪峰

哈希碰撞与生日攻击

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值