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

通过哈希算法,我们可以验证一段数据是否有效,方法就是对比该数据的哈希值,例如,判断用户口令是否正确,我们用保存在数据库中的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. 大数据基础篇----jvm的知识点归纳-5个区和垃圾回收机制

    一直对jvm看了又忘,忘了又看的.今天做一个笔记整理存放在这里. 我们先看一下JVM的内存模型图: 上面有5个区,这5个区干嘛用的呢? 我们想象一个场景: 我们有一个class文件,里面有很多的类的定 ...

  2. python初级 2 字符串格式化

    一.回顾 上次我们讲解的数据类型,有int,float,str,bool,NoneType五种 前两种和后两种都比较简单,str较为复杂 二.字符串格式化的使用场景: 有一种字符串, xxx 的内容都 ...

  3. VMware 虚拟机磁盘

    创建磁盘时,会进行两个操作:分配空间.置零 1.厚置备延迟置零: 默认的创建格式,创建磁盘时,直接从磁盘分配空间,但对磁盘保留数据不 置零.所以当有I/O操作时,只需要做置零的操作. 磁盘性能较好,时 ...

  4. titlesplit

    /** * Created by lkl on 2017/6/26. *///spark-shell --driver-class-path /home/hadoop/test/mysqljdbc.j ...

  5. word中替换【换行符】与【回车符】

  6. 【!Important】Zookeeper用来做什么的,有几种类型的节点

    zookeeper=文件系统+通知机制 一.Zookeeper提供了什么 1.文件系统 Zookeeper维护一个类似文件系统的数据结构 每个子目录项如NameService都被称为znoed,和文件 ...

  7. Orleans学习总结(五)--监控篇

    上篇说完了Orleans学习总结(四)--集群配置篇,这次我们来说下监控 Orleans有一个强大的社区,为Orleans开发着各种各样的扩展工具,我们用的是OrleansDashboard.Dash ...

  8. Linux下makefile学习

    [make是什么?] make是一个命令工具,是一个解释makefile中指令的命令工具.它可以简化编译过程里面所下达的指令,当执行 make 时,make 会在当前的目录下搜寻 Makefile ( ...

  9. js 去掉花括号

    "asd {{name}} {{age}}".replace(/{{(.*?)}}/g,'$1'); // "asd name age" "asd { ...

  10. Jenkins Docker安装及Docker build step插件部署配置

    生产部署环境:A:192.168.1.2 B:192.168.1.3  两台服务器系统均是Centos 7.3 , Docker版本都1.12.6 Jenkins安装操作步骤: 1.在A服务器上使用命 ...