python 密码学示例——理解哈希(Hash)算法

Hash 是密码学安全性的基石,它引入了单向函数(one-way function)和指纹(fingerprint)的概念。即:

  • 对于任意输入,都可以产生相同的、唯一的输出值
  • 输出值中不包含输入值的任何线索

一、保密性(confidentiality)与完整性(integrity)

简单来说,信息的保密性确保除授权人员以外的任何人都无法读取该消息,信息的完整性则确保除授权人员以外的任何人都无法修改该消息。
很多时候一段加密的消息无法被他人读取和理解(保密性),并不意味着该密文不会在传播过程中被截取和恶意修改(完整性)。

信息摘要(message digest)或指纹(fingerprint)技术即用于验证信息的完整性。

信息摘要需满足的基本条件为:

  • 相同的文档永远会生成相同的摘要(能够作为身份线索)
  • 生成的摘要“感觉”是随机的,即摘要中不包含原始文档的任何信息(无法被破解)

信息摘要也被称作指纹,即可以代表某份文档“身份”的一小段数据,类似于人类的指纹。
每个人都可以通过指纹验证其身份,但该指纹并不包含其身体的所有信息。文档的指纹也是如此,可以很方便快速的通过文档内容计算得出一小段唯一的指纹数据作为其身份证明,但是只有指纹数据就几乎不可能得出原始文档的内容。

对于两份文档,只需要比对其信息摘要(指纹)是否一致,就可以确保其内容是否相同,在传播过程中是否被人恶意修改。同时该指纹信息也不会造成原始文档本内容的泄露。

二、MD5

MD5 是一种比较古老的哈希算法,其名字中的 MD 即代表 message digest。它可以从任意大小的文档计算出一个唯一的 16 字节长度的摘要数据。

PS:鉴于 MD5 较悠久的历史和不够长的摘要长度,不推荐在安全性很敏感的场景中使用该算法。

>>> from hashlib import md5
>>> md5(b'alice').hexdigest()
'6384e2b2184bcbf58eccf10ca7a6563c'
>>> md5(b'bob').hexdigest()
'9f9d51bc70ef21ca5c14f307980a29d8'
>>> md5(b'balice').hexdigest()
'6760742ebf884c998752b4e082b78224'
>>> md5(b'cob').hexdigest()
'386685f06beecb9f35db2e22da429ec9'
>>> md5(b'a').hexdigest()
'0cc175b9c0f1b6a831c399e269772661'
>>> md5(b'aa').hexdigest()
'4124bc0a9335c27f086f24ba207a4912'
>>> md5(b'aa' * 100000).hexdigest()
'561b1994f6baacd6e5eaf4baaa12849f'
>>> md5(b'alice').hexdigest()
'6384e2b2184bcbf58eccf10ca7a6563c'

从输出中可以看出,针对不同的输入内容(即便相似度很高,比如 bob 和 cob),摘要算法生成的输出是发散的,彼此之间没有相似性,像是随机生成的结果。
但是对于任意相同的输入,生成的摘要数据则都是确定的、唯一的。

三、哈希算法的规则

一般我们提到哈希算法,都会关联到密码学、安全性等场景中,实际上我们很早就接触了一种完全“非密码学”的哈希场景。比如小时候跟老师学习判断一个数是奇数还是偶数。。。
从本质上看,哈希函数的目的是将巨大(甚至无穷大)数量的事物映射到一个相对较小的数据集中。比如 MD5,不管输入的文档有多大,最终都会生成一个固定长度(16 字节)的十六进制数字作为指纹。
这就意味着 MD5 的输入集合,实际上是大于其输出集合的。即只要输入文档的集合足够大(很大很大),就有可能出现重复的指纹信息。

这和判断数字奇偶是相通的。不管某个数字有多大多奇特,我们永远可以将它“压缩”成奇数或偶数,用 1 bit 的 1 或 0 表示就可以。但是只说明某个未知数字是奇数(或偶数),我们就无法猜出该数字的准确值。

上面的逻辑验证了哈希函数共有的 3 个特性:

  • consistency(一致性):相同的输入只会生成相同的输出信息
  • compression(压缩):可以将体量很大的输入压缩成一个固定大小的输出
  • lossiness(有损的):只通过检查输出无法反向计算出输入值

但是对于一个满足密码学安全的哈希函数而言,除以上三点以外还需要具有如下属性:

  • Preimage resistance
  • Second-preimage resistance
  • Collision resistance

Preimage Resistance

哈希函数的 preimage 是指能够生成同一个特定指纹的所有输入的合集。即对于某个哈希函数 H 与摘要 k,所有能够生成 k 的输入值 x (满足 H(x) = k)共同组成了 H 与 k 的 preimage。

preimage resistance 的意义即为,在仅仅只是知晓某个摘要的前提下,通过有限的计算无法获取其 preimage 中的任何一个元素。即只通过结果无法知晓输入。
摘要中不包含原始文档的任何信息(lossiness),无法通过逆向运算的方式由摘要反推出原始输入。只能随机地尝试任意输入,以期碰巧得到同样的摘要信息(暴力破解)。

因此前面提到的奇偶函数就不能作为一个安全的哈希函数使用。假设使用奇偶作为哈希函数(奇数输出 1,偶数输出 0),则对于摘要 1,总可以很轻易的在 preimage(此处是全体奇数)中找到任意多个摘要同为 1 的元素。这意味着原始输入可以轻易被修改而不影响指纹数据,则该指纹作为信息完整性的验证条件就失去了意义。

但是对于较安全的哈希算法如 MD5,由 MD5(x) = ca8a0fb205782051bd49f02eae17c9ee 就无法在有限的计算内找到确定的 x 的值。
MD5 生成 16 字节(16 * 8 = 128bit)长度的摘要,其中可以包含 2^128 种不同的数字组合。因此使用暴力破解的话,最多需要尝试 2^128 = 340282366920938463463374607431768211456 次!
假设每秒钟可以尝试一百万条输入,仍需要 10^26 年完成所有验证操作!

Second-Preimage Resistance 与 Collision Resistance

second-primage resistance 是指即便知晓某个原始文档以及由该文档生成的摘要数据,仍很难计算可以出生成同样摘要的另一个不同的文档。
即在已知 MD5(alice) = 384e2b2184bcbf58eccf10ca7a6563c 的情况下,仍无法找出除 alice 以外的另一个输入生成同样的摘要。为了寻求可以替换掉 alice 的另一个值,同时不影响摘要认证,达到混淆的目的,最终仍需使用暴力破解的方式。

collision resistance 是指很难找出任意两个生成相同摘要(相同而非特定)的输入值。
可以参考“生日问题”,即在一个班级中,存在两个生日为同一天的学生的概率远比存在一个生日为特定日期的学生的概率大得多。

collision resistance 的意义在于,无法故意找出两套符合同一指纹的输入以达到混淆的目的。比如 MD5 算法:

>>> from hashlib import md5
>>> md5('bob').hexdigest()
'9f9d51bc70ef21ca5c14f307980a29d8'
>>> md5('cob').hexdigest()
'386685f06beecb9f35db2e22da429ec9'

对于很相似的输入 bob 和 cob,其指纹信息的差异却非常大,没有任何可供预测的规律。这得益于一种称为 avalanche property 的特性:输入的微小变化总可以在输出中产生巨大的无法预测的差异。

由前面提到的生日问题可知,找出两个生成相同指纹的元素远比找出某个可以生成特定指纹的元素要容易的多。以 MD5 算法的暴力破解为例,后者往往需要做 2^128 次尝试,而前者只需要 2^64 次尝试。
现实中 MD5 的 collision resistance 远非想象中那么优异,甚至存在一种非暴力破解的方式 能够在一小时以内攻破 MD5 的 collision resistance。
所以尽量不要使用 MD5 这个已经不再维护超过 10 年、安全漏洞存在 20 年的古老算法。

参考资料

Practical Cryptography in Python: Learning Correct Cryptography by Example

以上就是python密码学示例——理解哈希(Hash)算法的详细内容,更多关于python 哈希(Hash)算法的资料请关注我们其它相关文章!

(0)

相关推荐

  • python实现哈希表

    复制代码 代码如下: #! /usr/bin/env python#coding=utf-8#实现哈希表(线性地址再散列) def ChangeKey(key,m,di):    key01=(key+di) % m    return key01 a=raw_input("Please entry the numbers:\n").split()m=len(a)dict01={}for i in a:    key=int(i)%m    if "%s"%key

  • python如何随机生成高强度密码

    本文实例为大家分享了python随机生成高强度密码的具体代码,供大家参考,具体内容如下 import random import re # 字母类型 englishChar = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'l', 'k', 'j', 'h', 'g', 'f', 'd', 's', 'a', 'z', 'x', 'c', 'v', 'b', 'n', 'm'] # 数字类型 numberChar = ['1', '2',

  • Python设计密码强度校验程序

    程序介绍 本程序利用 1.密码必须由数字.字母及特殊字符三种组合 2.密码只能由字母开头 3.密码长度不能低于16位 来判断密码程度. 首先,把可输入的字符写进去: symbols = r'''`!@#$%^&*()_+-=/*{}[]\|;:?/<>''' chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' nums = '0123456789' 然后开始循环并判断密码长度: while 1: print('-

  • 使用python实现哈希表、字典、集合操作

    哈希表 哈希表(Hash Table, 又称为散列表),是一种线性表的存储结构.哈希表由一个直接寻址表和一个哈希函数组成.哈希函数h(k)将元素关键字k作为自变量,返回元素的存储下标. 简单哈希函数: 除法哈希:h(k) = k mod m乘法哈希:h(k) = floor(m(kA mod 1)) 0<A<1 假设有一个长度为7的数组,哈希函数h(k) = k mod 7,元素集合{14, 22, 3, 5}的存储方式如下图: 哈希冲突 由于哈希表的大小是有限的,而要存储的值的总数量是无限的

  • python实现图像检索的三种(直方图/OpenCV/哈希法)

    简介: 本文介绍了图像检索的三种实现方式,均用python完成,其中前两种基于直方图比较,哈希法基于像素分布. 检索方式是:提前导入图片库作为检索范围,给出待检索的图片,将其与图片库中的图片进行比较,得出所有相似度后进行排序,从而检索结果为相似度由高到低的图片.由于工程中还包含Qt界面类.触发函数等其他部分,在该文档中只给出关键函数的代码. 开发系统:MacOS 实现方式:Qt + Python 方法一:自定义的直方图比较算法 a) 基本思路 遍历图片像素点,提取R\G\B值并进行对应的计数,得

  • 详解python实现可视化的MD5、sha256哈希加密小工具

    本文主要介绍了详解python实现可视化的MD5.sha256哈希加密小工具,分享给大家,具体如下: 效果图: 刚启动的状态 输入文本.触发加密按钮后支持复制 超过十条不全量显示 代码 import hashlib import tkinter as tk #窗口控制 windowss=tk.Tk() windowss.title('Python_md5')#窗口title,并非第一行 windowss.geometry('820x550') windowss.resizable(width=T

  • python 哈希表实现简单python字典代码实例

    这篇文章主要介绍了python 哈希表实现简单python字典代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 class Array(object): def __init__(self, size = 32, init = None): self._size = size self._items = [init] * size def __getitem__(self, index): return self._items[index

  • 用Python实现通过哈希算法检测图片重复的教程

    Iconfinder 是一个图标搜索引擎,为设计师.开发者和其他创意工作者提供精美图标,目前托管超过 34 万枚图标,是全球最大的付费图标库.用户也可以在 Iconfinder 的交易板块上传出售原创作品.每个月都有成千上万的图标上传到Iconfinder,同时也伴随而来大量的盗版图.Iconfinder 工程师 Silviu Tantos 在本文中提出一个新颖巧妙的图像查重技术,以杜绝盗版. 我们将在未来几周之内推出一个检测上传图标是否重复的功能.例如,如果用户下载了一个图标然后又试图通过上传

  • python 密码学示例——理解哈希(Hash)算法

    Hash 是密码学安全性的基石,它引入了单向函数(one-way function)和指纹(fingerprint)的概念.即: 对于任意输入,都可以产生相同的.唯一的输出值 输出值中不包含输入值的任何线索 一.保密性(confidentiality)与完整性(integrity) 简单来说,信息的保密性确保除授权人员以外的任何人都无法读取该消息,信息的完整性则确保除授权人员以外的任何人都无法修改该消息. 很多时候一段加密的消息无法被他人读取和理解(保密性),并不意味着该密文不会在传播过程中被截

  • Python密码学Caesar Cipher凯撒密码算法教程

    目录 凯撒密码算法 输出 说明 凯撒密码算法的黑客攻击 在最后一章中,我们处理了反向密码.本章详细讨论了凯撒密码. 凯撒密码算法 凯撒密码的算法具有以下特征; Caesar Cipher Technique是一种简单易用的加密技术方法. 这是一种简单的替换密码类型. 每个纯文本字母都被一个字母替换,字母的位数固定不变./p> 下图描绘了Caesar密码算法实现的工作原理 : Caesar密码算法的程序实现如下 : def encrypt(text,s): result = ""

  • python 密码学示例——凯撒密码的实现

    凯撒密码 是密码学中的一种简单的 替换加密 技术.明文中的所有字符都会替换为其按照字母表顺序向左(或向右)偏移一定量后得到的新字母,作为加密后密文. 如当偏移量为 3 时,明文中所有的字母 A 将被替换成字母 D,B 替换成 E,以此类推. 若收到密文的同时已知加密时使用的偏移量,就可以快速地通过逆运算获取到最初的明文. 下面两张图展示了当偏移量为 8 时明文字母与密文字母的对应关系(图一即凯撒密码轮盘,外层为明文,内层为密文,可旋转以改变偏移量)以及实际的加密过程(图二): PS:对一段明文消

  • Java语言Consistent Hash算法学习笔记(代码示例)

    本文研究的主要是ConsistentHashing算法代码. 一致性哈希(Consistent Hash) 协议简介 一致性哈希算法在1997年由麻省理工学院提出(参见0),设计目标是为了解决因特网中的热点(Hot pot)问题,初衷和CARP十分类似.一致性哈希修正了CARP使用的简单哈希算法带来的问题,使得DHT可以在P2P环境中真正得到应用. 哈希算法 一致性哈希提出了在动态变化的Cache环境中,哈希算法应该满足的4个适应条件: 平衡性(Balance) 平衡性是指哈希的结果能够尽可能分

  • 基于Python实现Hash算法

    目录 1 前言 2 一般hash算法 2.1 算法逻辑 2.2 代码实现 2.3 总结 3 一致性hash算法 3.1 算法逻辑 3.2 代码实现 3.3 总结 1 前言 Simhash的算法简单的来说就是,从海量文本中快速搜索和已知simhash相差小于k位的simhash集合,这里每个文本都可以用一个simhash值来代表,一个simhash有64bit,相似的文本,64bit也相似,论文中k的经验值为3.该方法的缺点如优点一样明显,主要有两点,对于短文本,k值很敏感:另一个是由于算法是以空

  • Python密码学ROT13算法教程

    目录 ROT13算法的解释 示例 程序代码 缺点 ROT13算法的分析 到目前为止,您已经了解了反向密码和Caesar密码算法.现在,让我们讨论一下ROT13算法及其实现. ROT13算法的解释 ROT13密码是指缩写形式旋转方式13个地方.这是Caesar Cipher的一个特例,其中shift始终为13.每个字母移动13个位置以加密或解密消息. 示例 下图以图形方式解释了ROT13算法过程 : 程序代码 ROT13算法的程序实现如下 from string import maketrans

  • Python密码学XOR算法编码流程及乘法密码教程

    目录 XOR算法 代码 输出 说明 乘法密码 Python中乘法密码的基本调制函数如下: 在本章中,让我们了解XOR过程及其在Python中的编码以及乘法密码的教程 XOR算法 XOR算法的加密和解密转换ASCII字节格式的纯文本,并使用XOR过程将其转换为指定的字节.它为用户提供以下优势 : 快速计算 没有区别标记左侧和右侧 易于理解和分析 代码 您可以使用以下代码执行XOR过程 : def xor_crypt_string(data, key = 'awesomepassword', enc

  • PHP实现的一致性HASH算法示例

    本文实例讲述了PHP实现的一致性HASH算法.分享给大家供大家参考,具体如下: <?php // +---------------------------------------------------------------------- // | Perfect Is Shit // +---------------------------------------------------------------------- // | PHP实现:一致性HASH算法 // +--------

  • Python实现的计算马氏距离算法示例

    本文实例讲述了Python实现的计算马氏距离算法.分享给大家供大家参考,具体如下: 我给写成函数调用了 python实现马氏距离源代码: # encoding: utf-8 from __future__ import division import sys reload(sys) sys.setdefaultencoding('utf-8') import numpy as np def mashi_distance(x,y): print x print y #马氏距离要求样本数要大于维数,

  • python 机器学习之实现朴素贝叶斯算法的示例

    特点 这是分类算法贝叶斯算法的较为简单的一种,整个贝叶斯分类算法的核心就是在求解贝叶斯方程P(y|x)=[P(x|y)P(y)]/P(x) 而朴素贝叶斯算法就是在牺牲一定准确率的情况下强制特征x满足独立条件,求解P(x|y)就更为方便了 但基本上现实生活中,没有任何关系的两个特征几乎是不存在的,故朴素贝叶斯不适合那些关系密切的特征 from collections import defaultdict import numpy as np from sklearn.datasets import

随机推荐