Python学习_基础_23_常用模块之hashlib模块

Python-常用模块

一、hashlib模块

①__什么是hash(哈希)?

hash是一类算法,该算法接收传入的内容,经过运算得到一串hash值。

hash值的特点:

  1. 只要传入的内容一样,得到的hash值必然一样
  2. 不能由hash值返解出传入的内容
  3. 不管传入的内容有多大,只要使用的hash算法不变,得到的hash值长度是固定的

②哈希的用途

  1. 用途一:利用特点2实现密码的密文传输与验证
  2. 用途二:利用特点1、3实现文件完整性校验

③如何用哈希(import hashlib)

hash算法就像一座工厂,有着不同的加工流水线,流水线接收送进来的原材料(使用update()运送原材料),经过加工返回的产品就是hash值(使用hexdigest()拿到产品)。

import hashlib

m = hashlib.md5()  # 选择md5流水线
m.update('hello'.encode('utf-8'))  # 使用update()运送原材料,格式选择utf-8
m.update('world'.encode('utf-8'))  # 继续运送原材料

res = m.hexdigest()  # 一次性取出所有产品,拿到的是'helloworld'的哈希值
print(res)  # fc5e038d38a57032085441e7fe7010b0
print(type(res))  # <class 'str'>  得到的值是字符串类型
import hashlib

m = hashlib.sha256()  # 选择sha256流水线
m.update('hello'.encode('utf-8'))
m.update('world'.encode('utf-8'))

res = m.hexdigest()
print(res)  # 936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af

针对用途一:

把一段数据分开update多次,与一次update这段数据,得到的结果一样。

import hashlib

m = hashlib.md5()
m.update('hello'.encode('utf-8'))
m.update('world'.encode('utf-8'))
res = m.hexdigest()  # 'helloworld'
print(res)  # fc5e038d38a57032085441e7fe7010b0

m1 = hashlib.md5('he'.encode('utf-8'))
m1.update('llo'.encode('utf-8'))
m1.update('w'.encode('utf-8'))
m1.update('orld'.encode('utf-8'))
res = m1.hexdigest()  # 'helloworld'
print(res)  # fc5e038d38a57032085441e7fe7010b0

针对用途二:

我们要实现文件的完整性校验,无非就是把文件扔进哈希工厂里加工,看看得到的哈希值一不一样。

import hashlib

m = hashlib.md5()
m.update(文件所有的内容)
m.hexdigest()

可是这样子做有一个问题,如果文件体积过大,把这个大文件从头至尾都校验一遍是很消耗资源的一件事情,该怎么优化呢?

我们可以随机选定一段内容,放进去校验,这样子就可以在大概率的情况下保证文件是完整的。但说实在的,我们也不能百分之百确定文件的完整性,能做的也只是多来几次随机校验。


二、撞库与密码加盐

撞库

我们现在知道,利用hashlib模块可以对密码进行密文加工和验证。加密算法虽然非常厉害,但有时候依然存在缺陷,即:虽然它自身不支持反解,但我们可以通过撞库实现暴力破解。

import hashlib

m = hashlib.md5()
m.update('admin123'.encode('utf-8'))
res = m.hexdigest()
print(res)  # 0192023a7bbd73250516f069df18b500

我们看到,密码admin123的哈希值是0192023a7bbd73250516f069df18b500。

现在如果我们知道密码的哈希值,并且知道密码是由字母adimn与数字123通过未知顺序组成的,我们就可以根据已知信息制作出密码字典。

import hashlib

passwds = [
    'admin123',
    '123admin',
    'a123dmin',
    'ad123min',
    'ad123min',
    'adm123in',
    'admi123n',
    '省略...'
]
dic = {}
for p in passwds:
    res = hashlib.md5(p.encode('utf-8'))
    dic[p] = res.hexdigest()

我们有了密码字典,就可以撞库了。(而像这种密码字典,网络上有很多很多)

mima = '0192023a7bbd73250516f069df18b500'
for k, v in dic.items():
    if v == mima:
        print('撞库成功,明文密码是:%s' % k)
        break

撞库成功,明文密码是:admin123


密码加盐(盐:自定义加工)

密码加盐可以增加撞库的成本,就是对密码进行自定义加工之后再进行哈希算法加密。

import hashlib

m = hashlib.md5()

m.update('喜羊羊'.encode('utf-8'))
m.update('admin'.encode('utf-8'))
m.update('灰太狼'.encode('utf-8'))
print(m.hexdigest())  # 2059b347caf000611fec6ec9b0dc9a30

像上面这样,就是对密码先进行了开头结尾的加工之后再进行哈希算法加密。

当然我们也可以这样:得到了一个密码字符串后进行自主分割,再给其中添加自定义的内容后进行合并,进而再使用哈希算法加密。

这样子的话,要想进行撞库破解,就先要知道加盐的内容。加盐的内容知道了后,还需要知道加盐的位置在哪里。

当我们在前台输入密码之后,输入的内容就会先进行处理加盐,再进行哈希算法加密,得到的哈希值与后台保存的密码进行比对,如果一样则登陆成功。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值