python hash

发布时间 2023-12-12 22:32:50作者: ArvinDu

python 中的 hash

我的博客

程序源码

原书:《Python全栈安全》

这里使用 python 3.8,使用哈希函数计算消息的摘要信息,得到其哈希值(散列值)。在 python 下可以使用如下语句得到消息的哈希值:

message='message'
hash(message)

哈希具有如下特性:

  1. 确定性,相同的消息使用同一个哈希函数计算得到相同的哈希值
  2. 固定长度的哈希值,输入的消息长度是不等的,计算得到的哈希值是具有固定长度的
  3. 雪崩效应,消息的细微差别,会导致哈希值的巨大区别

哈希函数属性

  1. 单向函数,难以通过逆向工程破解
  2. 弱抗碰撞性,已知一条消息,难以查找到另一条有相同哈希值的消息
  3. 强抗碰撞性,对所有的消息,难以查找到两条具备相同哈希值的消息

检测数据完整性

计算数据的哈希值,重新计算的哈希值与旧值做比较,若二者不一致,则表明消息不具备完整性。

python 支持的哈希函数

python 有 hashlib 模块:

import hashlib
sorted(hashlib.algorithms_available)
sorted(hashlib.algorithms_guaranteed)
>>> sorted(hashlib.algorithms_guaranteed)
['blake2b', 'blake2s', 'md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512', 'sha512', 'shake_128', 'shake_256']

安全与不安全的哈希函数

在上面列出的一些哈希算法中,有一些是安全的算法,一些是已经被破解的算法。

MD5 算法在 2004 年就已经被证实存在碰撞。

SHA-1 算法在 2017 年由谷歌发布了第一次碰撞。

若以前的系统使用了上面的两种算法,那么出于安全考虑,需要重构代码。

python 中的加密哈希

import hashlib
named = hashlib.sha256()#命名构造函数
generic = hashlib.new('sha256')#通用构造函数

下面两条消息可以展示MD5算法的碰撞:

'd131dd02c5e6eec4693d9a0698aff95c2fcab58712467eab4004583eb8fb7f8955ad340609f4b30283e488832571415a085125e8f7cdc99fd91dbdf280373c5bd8823e3156348f5bae6dacd436c919c6dd53e2b487da03fd02396306d248cda0e99f33420f577ee8ce54b67080a80d1ec69821bcb6a8839396f9652b6ff72a70'

'd131dd02c5e6eec4693d9a0698aff95c2fcab50712467eab4004583eb8fb7f8955ad340609f4b30283e4888325f1415a085125e8f7cdc99fd91dbd7280373c5bd8823e3156348f5bae6dacd436c919c6dd53e23487da03fd02396306d248cda0e99f33420f577ee8ce54b67080280d1ec69821bcb6a8839396f965ab6ff72a70'

验证程序如下:

from hashlib import md5

x = bytearray.fromhex('d131dd02c5e6eec4693d9a0698aff95c2fcab58712467eab4004583eb8fb7f8955ad340609f4b30283e488832571415a085125e8f7cdc99fd91dbdf280373c5bd8823e3156348f5bae6dacd436c919c6dd53e2b487da03fd02396306d248cda0e99f33420f577ee8ce54b67080a80d1ec69821bcb6a8839396f9652b6ff72a70')
y = bytearray.fromhex('d131dd02c5e6eec4693d9a0698aff95c2fcab50712467eab4004583eb8fb7f8955ad340609f4b30283e4888325f1415a085125e8f7cdc99fd91dbd7280373c5bd8823e3156348f5bae6dacd436c919c6dd53e23487da03fd02396306d248cda0e99f33420f577ee8ce54b67080280d1ec69821bcb6a8839396f965ab6ff72a70')
print(x==y)
print(md5(x).digest() == md5(y).digest())

我们可以将消息一股脑的给到哈希函数,计算哈希值,也可以通过使用 update 的方式迭代计算哈希值,使用 update 方式计算得到的哈希值与迭代计算得到的哈希值一致:

from hashlib import sha256

once = sha256()
once.update(b'message')
many = sha256()
many.update(b'm')
many.update(b'e')
many.update(b's')
many.update(b's')
many.update(b'a')
many.update(b'g')
many.update(b'e')
print(once.digest() == many.digest())

确定了消息,确定了哈希算法,无论什么平台、什么语言,计算得到的哈希值是一致的。

哈希不同于校验和

哈希函数具有更强的抗碰撞性,而校验和函数的速度更快。