【微语】不应当急于求成,应当去熟悉自己的研究对象,锲而不舍,时间会成全一切。凡事开始最难;然而最难的是何以善终

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

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

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

这实际上就是Hmac算法:Keyed-Hashing for Message Authentication Code。它通过一个标准算法,在计算哈希的过程中,把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)
>>> h.hexdigest()
'fa4ee7d173f2d97ee79022d1a7355bcf'

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

练习

将上一节的salt改为标准的hmac算法,验证用户口令:

# -*- coding: utf-8 -*-
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', ''),
'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', '')
assert login('bob', 'abc999')
assert login('alice', 'alice2008')
assert not login('michael', '')
assert not login('bob', '')
assert not login('alice', 'Alice2008')
print('ok')

【python基础】hmac的更多相关文章

  1. Python基础-week05

    本节大纲:Author:http://www.cnblogs.com/Jame-mei 模块介绍 time & datetime模块 random os sys shutil json &am ...

  2. python基础之socket编程 (转自林海峰老师)

    python基础之socket编程   阅读目录 一 客户端/服务器架构 二 osi七层 三 socket层 四 socket是什么 五 套接字发展史及分类 六 套接字工作流程 七 基于TCP的套接字 ...

  3. python基础系列教程——Python3.x标准模块库目录

    python基础系列教程——Python3.x标准模块库目录 文本 string:通用字符串操作 re:正则表达式操作 difflib:差异计算工具 textwrap:文本填充 unicodedata ...

  4. python基础-第六篇-6.2模块

    python之强大,就是因为它其提供的模块全面,模块的知识点不仅多,而且零散---一个字!错综复杂 没办法,二八原则抓重点咯!只要抓住那些以后常用开发的方法就可以了,哪些是常用的?往下看--找答案~ ...

  5. python之最强王者(2)——python基础语法

    背景介绍:由于本人一直做java开发,也是从txt开始写hello,world,使用javac命令编译,一直到使用myeclipse,其中的道理和辛酸都懂(请容许我擦干眼角的泪水),所以对于pytho ...

  6. Python开发【第二篇】:Python基础知识

    Python基础知识 一.初识基本数据类型 类型: int(整型) 在32位机器上,整数的位数为32位,取值范围为-2**31-2**31-1,即-2147483648-2147483647 在64位 ...

  7. Python小白的发展之路之Python基础(一)

    Python基础部分1: 1.Python简介 2.Python 2 or 3,两者的主要区别 3.Python解释器 4.安装Python 5.第一个Python程序 Hello World 6.P ...

  8. Python之路3【第一篇】Python基础

    本节内容 Python简介 Python安装 第一个Python程序 编程语言的分类 Python简介 1.Python的由来 python的创始人为吉多·范罗苏姆(Guido van Rossum) ...

  9. 进击的Python【第三章】:Python基础(三)

    Python基础(三) 本章内容 集合的概念与操作 文件的操作 函数的特点与用法 参数与局部变量 return返回值的概念 递归的基本含义 函数式编程介绍 高阶函数的概念 一.集合的概念与操作 集合( ...

  10. 进击的Python【第二章】:Python基础(二)

    Python基础(二) 本章内容 数据类型 数据运算 列表与元组的基本操作 字典的基本操作 字符编码与转码 模块初探 练习:购物车程序 一.数据类型 Python有五个标准的数据类型: Numbers ...

随机推荐

  1. npm WARN unmet dependency错误解决方法

    在MAC上安装webpack以及reactjs等其它组件时,安装太慢卡住不动,直接ctrl+c终止后,再npm install后出npm WARN unmet dependency错误,npm cac ...

  2. Entlib DAAB映射枚举类型

    1. IRowMapper<UserDto> addressMapper = MapBuilder<UserDto> .MapAllProperties() .Map(p =& ...

  3. SASS常用语法

    原文地址:这里 @charset "UTF-8"; /** * 自定义变量 */ $blue: #1875e7; div { color: $blue; } /** * 变量要嵌在 ...

  4. PCL中使用FLANN库(2)

    接着上一篇的介绍继续 关于在使用readHeader函数读取点云数据头的类型的代码(Read a point cloud data header from a PCD file.) pcl::PCLP ...

  5. Java知多少(12)运算符

    Java中的运算符和C/C++相差无几. 数学运算符 数学运算,结果为一个数值.见下表: 运算符 说明 举例 + 加法 1 + 2 - 减法 4 - 3.4 * 乘法 7 * 1.5 / 除法 3.5 ...

  6. token令牌和jwt

    用户登录,后端生成token返回给前端 前端拿到token,以后每次登录使用header里的token进行权限验证 后端接收到前端传来的token,如果是通过数据库或redis或session进行比对 ...

  7. Intellij IDEA 2015 导入MyEClipse工程

    一.步骤说明 File->New->Projet from existing sources,选择要导入的项目,并且导入项目; 打开 “open module settings”进行设置: ...

  8. CentOS7 yum方式安装MariaDB 10.2.13-1

    注:以下步骤都是以root身份运行. 一.建立mariadb.repo 1,编辑新文件,命令:vim  /etc/yum.repos.d/mariadb.repo 2,输入如下内容,保存退出 [mar ...

  9. linux dns 工具包 -- bind-utils

    https://www.cnblogs.com/274914765qq/p/4817941.html

  10. android 中文api

    http://www.embeddedlinux.org.cn/androidapi/