zoukankan      html  css  js  c++  java
  • Python hashlib and hmac

    hashlib

    hashlib提供了常用的摘要算法:MD5, SHA1等等

    摘要算法:也成哈希算法,散列算法。通过一个函数把任意长度的数据转换成一个长度固定的数据串。主要用在存储一些不能被修改和查看的数据。

    如用户名和密码存储在数据库中,但是不能明文存储,通过摘要算法转换成一串数据,安全性比明文存储要好。

    算法MD5:hashlib.md5(Bytes)

    常用的摘要算法MD5, 输入的参数是Bytes类型,生成结果是固定的128bit, 通常用一个32位的16进制字符串表示

    计算一个字符串的MD5值,传入string类型的参数

    import hashlib

    和直接传入Bytes参数效果一样

    如果数据量很大,可以多次调用md5.update(), 效果一样

     

    但是一定要注意,多次调用的时候,字符串分隔后中间的符号一定要保留,否则结果将会不一样,

    如下面的例子中, ‘a’后面少了一个空格,结果相当于‘this is apassword’ 而不是‘this is a password’:

    算法SHA1:hashlib.sha1(bytes),用法和MD5相同,生成160bit字节,通常用40位的16进制字符串表示

    Hmac

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

    hmac.new(key, message, digestmod='MD5')

    key 和message都必须是Bytes类型

     

    下面是分别用hashlib 和 hmac实现的密码验证:

    用hashlib实现:

    # _*_ coding:utf-8_*_
    import hashlib, random


    def get_md5(s):
    return hashlib.md5(s.encode('utf-8')).hexdigest()


    class User(object):
    def __init__(self, username, password):
    self.username = username
    self.salt = ''.join([chr(random.randint(48, 122)) for i in range(20)])
    self.password = get_md5(password + self.salt)

    db = {
    'michael': User('michael', '123456'),
    'bob': User('bob', 'abc999'),
    'alice': User('alice', 'alice2008')
    }


    def login(username, password):
    user = db[username]
    return user.password == get_md5(password + user.salt)
    # user.password 里传入的参数是db里的password
    # ==后面的get_md5里的password是用的login这里传入的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')

     

    用hmac实现

    # _*_ coding:utf-8 _*_
    import hmac, random


    def get_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 = get_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 == get_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')

    
    
    
  • 相关阅读:
    操作串口通信类(IO.Ports)SerialPort
    TreeView的数据源绑定—采用sqlite作为数据源,实现对treeview控件进行增删改查
    (Easy)打开指定的文件
    TreeView的数据源绑定—采用XML作为数据源,实现对treeview进行增删改查,之后回写XML文档
    linux sort,uniq,cut,wc命令详解
    轻快的VIM(六):恢复
    Python 常用模块大全(整理)
    定位oracle实例的当前跟踪文件名及路径
    查看session io
    查看pga使用
  • 原文地址:https://www.cnblogs.com/xiaohai2003ly/p/8709860.html
Copyright © 2011-2022 走看看