• hmac模块


    通过哈希算法,我们可以验证一段数据是否有效,方法就是对比该数据的哈希值,例如,判断用户口令是否正确,我们用保存在数据库中的password_md5对比计算md5(password)的结果,如果一致,用户输入的口令就是正确的。

    为了防止黑客通过彩虹表根据哈希值反推原始口令,在计算哈希的时候,不能仅针对原始输入计算,需要增加一个salt来使得相同的输入也能得到不同的哈希,这样,大大增加了黑客破解的难度。

    如果salt是我们自己随机生成的,通常我们计算MD5时采用 md5(message + salt) 。但实际上,把salt看做一个“口令”,加salt的哈希就是:计算一段message的哈希时,根据不通口令计算出不同的哈希。要验证哈希值,必须同时提供正确的口令。

    这实际上就是Hmac算法:Keyed-Hashing for Message Authentication。它通过一个标准算法,在计算哈希的过程中,把key混入计算过程中。

    和我们自定义的加salt算法不同,Hmac算法针对所有哈希算法都通用,无论是MD5还是SHA-1。采用Hmac替代我们自己的salt算法,可以使程序算法更标准化,也更安全。

    Python自带的hmac模块实现了标准的Hmac算法。我们来看看如何使用hmac实现带key的哈希。

    我们首先需要准备待计算的原始消息message,随机key,哈希算法,这里采用MD5,使用hmac的代码如下:

    1 import hmac
    2 
    3 message='Hello,world!'.encode('utf-8')
    4 key='secret'.encode('utf-8')
    5 
    6 h=hmac.new(key,message,digestmod='MD5')
    7 
    8 print(h.hexdigest())

    结果:

    "D:Program Files (x86)python36python.exe" F:/python从入门到放弃/7.3/hmac_module.py
    21db988f124ebc9fade5492afb9df52d
    
    Process finished with exit code 0

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

    练习

    将hashlib模块中的练习题 的salt改为标准的hmac算法,验证用户口令:

     1 # -*- coding: utf-8 -*-
     2 import hmac, random
     3 
     4 def hmac_md5(key, s):
     5     return hmac.new(key.encode('utf-8'), s.encode('utf-8'), 'MD5').hexdigest()
     6 
     7 class User(object):
     8     def __init__(self, username, password):
     9         self.username = username
    10         self.key = ''.join([chr(random.randint(48, 122)) for i in range(20)])
    11         self.password = hmac_md5(self.key, password)
    12 
    13 db = {
    14     'michael': User('michael', '123456'),
    15     'bob': User('bob', 'abc999'),
    16     'alice': User('alice', 'alice2008')
    17 }
    18 def login(username, password):
    19     user = db[username]
    20     return user.password == hmac_md5(user.key, password)
    21 
    22 # 测试:
    23 assert login('michael', '123456')
    24 assert login('bob', 'abc999')
    25 assert login('alice', 'alice2008')
    26 assert not login('michael', '1234567')
    27 assert not login('bob', '123456')
    28 assert not login('alice', 'Alice2008')
    29 print('ok')

    from:廖雪峰的官方网站

  • 相关阅读:
    后端开发应该掌握的 Redis 基础
    Code Review有什么好处?
    对不起,你那不叫努力,叫重复劳动
    老鸟程序员才知道的40个小技巧
    单例模式基础笔记
    最受IT公司欢迎的50款开源软件
    硬件:关于路由器、交换机、宽带猫的几个问题
    硬件:宽带猫(光猫)的基础知识
    python selenium模块使用出错解决,Message: ‘geckodriver’ executable needs to be in PATH
    python+selenium如何定位页面的元素,的几种定位元素的方法。
  • 原文地址:https://www.cnblogs.com/Mengchangxin/p/9263659.html
Copyright © 2020-2023  润新知