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')

    
    
    
  • 相关阅读:
    每日一水 POJ8道水题
    编译和使用 MySQL C++ Connector
    j2ee model1模型完成分页逻辑的实现 详解!
    DB查询分析器访问EXCEL时,要在表名前后加上中括弧或双引号
    指向结构体变量的指针
    EOSS V3.0 企业运营支撑系统(基于RBAC原理的权限管理)
    MybatisGen1.0 Mybatis JavaBean Mapper生成工具
    The table name must be enclosed in double quotation marks or sqare bracket while accessing EXCEL by
    资源-Android:Android
    软件-开发软件:Android Studio
  • 原文地址:https://www.cnblogs.com/xiaohai2003ly/p/8709860.html
Copyright © 2011-2022 走看看