zoukankan      html  css  js  c++  java
  • 模块之hashlib模块详解

    摘要算法简介

    Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等。

    什么是摘要算法呢?摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。

    举个例子,你写了一篇文章,内容是一个字符串'how to use python hashlib - by Michael',并附上这篇文章的摘要是'2d73d4f15c0db7f5ecb321b6a65e5d6d'。如果有人篡改了你的文章,并发表为'how to use python hashlib - by Bob',你可以一下子指出Bob篡改了你的文章,因为根据'how to use python hashlib - by Bob'计算出的摘要不同于原始文章的摘要。

    可见,摘要算法就是通过摘要函数f()对任意长度的数据data计算出固定长度的摘要digest,目的是为了发现原始数据是否被人篡改过。

    摘要算法之所以能指出数据是否被篡改过,就是因为摘要函数是一个单向函数,计算f(data)很容易,但通过digest反推data却非常困难。而且,对原始数据做一个bit的修改,都会导致计算出的摘要完全不同。

    我们以常见的摘要算法MD5为例,计算出一个字符串的MD5值:

    import hashlib
    
    md5 = hashlib.md5()
    md5.update('how to use md5 in python hashlib?'.encode('utf-8'))
    print(md5.hexdigest())
    
    # 结果: d26a53750bc40b38b65a520292f69306

    如果数据量很大,可以分块多次调用update(),最后计算的结果是一样的:

    import hashlib
    
    md5 = hashlib.md5()
    md5.update('how to use md5 in '.encode('utf-8'))
    md5.update('python hashlib?'.encode('utf-8'))
    print(md5.hexdigest())

    MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示。

    SHA1的结果是160 bit字节,通常用一个40位的16进制字符串表示。

    比SHA1更安全的算法是SHA256和SHA512,不过越安全的算法不仅越慢,而且摘要长度更长。

    hashlib模块的使用

    案例1: 设计一个验证用户登录的函数,根据用户输入的口令是否正确,返回True或False:

    # -*- coding: utf-8 -*-
    import hashlib
    
    db = {
        'michael': 'e10adc3949ba59abbe56e057f20f883e',
        'bob': '878ef96e86145580c38c87f0410ad153',
        'alice': '99b1c2188db85afee403b1536010c2c9'
    }
    
    def login(user, password):
        return user in db.keys() and db[user] == hashlib.md5(password.encode('utf-8')).hexdigest()
    
    assert login('michael', '123456')
    assert login('bob', 'abc999')
    assert login('alice', 'alice2008')
    assert not login('michael', '1234567')
    assert not login('bob', '123456')
    assert not login('alice', 'Alice2008')
    print('ok')

    采用MD5存储口令不一定很安全,黑客可以通过撞库的方式来进行破解密码。黑客可以事先计算出这些常用口令的MD5值,得到一个反推表, 最后通过反推表来得到密码的原文

    由于常用口令的MD5值很容易被计算出来,所以,要确保存储的用户口令不是那些已经被计算出来的常用口令的MD5,这一方法通过对原始口令加一个复杂字符串来实现,俗称“加盐”:

    def calc_md5(password):
        return get_md5(password + 'the-Salt')

    hmac模块详解

    “加盐”实际上就是Hmac算法:Keyed-Hashing for Message Authentication。它通过一个标准算法,在计算哈希的过程中,把key混入计算过程中。和我们自定义的加salt算法不同,Hmac算法针对所有哈希算法都通用,无论是MD5还是SHA-1。采用Hmac替代我们自己的salt算法,可以使程序算法更标准化,也更安全。

    Python自带的hmac模块实现了标准的Hmac算法。我们来看看如何使用hmac实现带key的哈希。我们首先需要准备待计算的原始消息message,随机key,哈希算法,这里采用MD5,使用hmac的代码如下:

    import hmac
    message = b'Hello, world!'
    key = b'secret'
    
    h = hmac.new(key, message, digestmod='MD5')
    # 如果消息很长,可以多次调用h.update(msg)
    print(h.hexdigest())
    
    
    # 'fa4ee7d173f2d97ee79022d1a7355bcf'

    可见使用hmac和普通hash算法非常类似。hmac输出的长度和原始哈希算法的长度一致。需要注意传入的key和message都是bytes类型,str类型需要首先编码为bytes

    案例:

    import hmac, random
    
    def hmac_md5(key, s):
        return hmac.new(key.encode('utf-8'), s.encode('utf-8'), 'MD5').hexdigest()
    
    class User(object):
        def __init__(self, username, password):
            self.username = username
            self.key = ''.join([chr(random.randint(48, 122)) for i in range(20)])
            self.password = hmac_md5(self.key, password)
    
    db = {
        'michael': User('michael', '123456'),
        'bob': User('bob', 'abc999'),
        'alice': User('alice', 'alice2008')
    }
    
    def login(username, password):
        user = db[username]
        return user.password == hmac_md5(user.key, password)
    
    # 测试:
    assert login('michael', '123456')
    assert login('bob', 'abc999')
    assert login('alice', 'alice2008')
    assert not login('michael', '1234567')
    assert not login('bob', '123456')
    assert not login('alice', 'Alice2008')
    print('ok')

    参照: https://www.liaoxuefeng.com/wiki/1016959663602400/1017686752491744#0

  • 相关阅读:
    【唯星宠物】——CSS/BootStrap/Jquery爬坑之响应式首页
    layui table数据渲染页面+筛选医生+在筛选日期一条龙2
    layui table数据渲染页面+筛选医生+在筛选日期一条龙
    拿到数组逗号分隔在循环拿到里面的数据,最后DOM插入页面
    解决跨域请求的几种方式
    MUI下拉刷新
    Java集合(6):理解Map
    Java集合(5):理解Collection
    Java集合(4):未获支持的操作及UnsupportedOperationException
    Java集合(3):使用Abstract类
  • 原文地址:https://www.cnblogs.com/featherwit/p/13280316.html
Copyright © 2011-2022 走看看