Python 哈希函数与消息认证实验
目录
- 前言
- 一、计算哈希值和消息认证
- 1.引入库
- 2.实现
- 二、哈希函数的雪崩效应
- 实现
- 三、暴力破解MD5
- 1.引入库
- 2.实现
- 总结
前言
提示:测试运行环境为 python3.7.5,IDE为Pycharm2020.1,文章包含三道题,分别是:1.计算哈希值和消息认证;2.哈希函数的雪崩效应;3.暴力破解MD5。复制过去的源码可能要改一下输出格式嗷。
一、计算哈希值和消息认证
题目描述:编写一个能计算文本MD5、SHA512和hmac的程序。
1.引入库
代码如下:
import hashlib
import hmac
from hashlib import md5, sha256, sha512
关于库的使用可见官方文档:
hmac — 基于密钥的消息验证
hashlib — 安全哈希与消息摘要
2.实现
实现–版本一:
# 一开始写的,为了过实验的版本
import hashlib
import hmac
from hashlib import md5, sha256, sha512def myhash(str):res = hashlib.md5(str.encode(encoding="utf-8"))print(res.hexdigest())def myhmac(key, str, mode):# param key:计算消息验证码的用到的密钥# param str:计算消息验证码的字符串# param mode: 使用的哈希函数key = key.encode(encoding="utf-8")str = str.encode(encoding="utf-8")if mode == 'md5':my_hmac = hmac.new(key, str, digestmod=md5)res1 = sha512(str)print(res1.hexdigest())print(my_hmac.hexdigest())elif mode == 'sha256':res1 = sha512(str)print(res1.hexdigest())my_hmac = hmac.new(key, str, digestmod=sha256)print(my_hmac.hexdigest())elif mode == 'sha512':res1 = sha512(str)print(res1.hexdigest())my_hmac = hmac.new(key, str, digestmod=sha512)print(my_hmac.hexdigest())if __name__ == "__main__":str = input()key = input()mode = input()myhash(str)myhmac(key, str, mode)
那会为了过实验,写的又臭又长,不美观也不好读,也就是实现个功能罢了,于是又跑去参考了BossXie同学的代码,看完之后直呼666,简洁得不像话,于是我也大致照着思路又写了一个改良版:
# 改良版import hashlib
import hmac
from hashlib import md5, sha256, sha512def myhash(str):res = hashlib.md5(str.encode(encoding="utf-8"))print("md5: " + res.hexdigest())def myhmac(key, str, mode):# param key:计算消息验证码的用到的密钥# param str:计算消息验证码的字符串# param mode: 使用的哈希函数key = key.encode(encoding="utf-8")str = str.encode(encoding="utf-8")my_hmac = hmac.new(key, str, mode)res1 = sha512(str)print("sha512 " + res1.hexdigest())print("hmac: " + my_hmac.hexdigest())if __name__ == "__main__":str = input()key = input()mode = input()myhash(str)myhmac(key, str, mode)
测试一下结果:
看着确实是要舒服很多呀~
二、哈希函数的雪崩效应
题目描述:编写一个能验证哈希函数MD5雪崩效应的程序。
(偷偷吐槽:这道题应该是本次实验最烦人的了,虽然说写完之后确实感觉不难,但是题目的提示真的太少了!可以查的资料也不多,是比较难写的,当然也可能是我太菜了)
实现
代码如下:
import hashlibdef encode(s):return ' '.join([bin(ord(c)).replace('0b', '') for c in s])def decode(s):return ''.join([chr(i) for i in [int(b, 2) for b in s.split(' ')]])# 该函数用于计算两个字符串不同的位数
def cmpcount(str1, str2):count = 0for i in range(0, len(str1)):times += 1if str1[i] != str2[i]:count += 1return countdef avalanche(str, nbyte, mbit):# param str:计算哈希值的字符串# param nbyte:str的第几个字节(从低位到高位数)# parem mbit: nbyte的第几个bit位(从低位到高位数)h1 = hashlib.md5(str.encode(encoding="utf-8")) # 获取原字符串的MD5h1 = h1.hexdigest()nbyte_place = len(str) - nbyte # 获取目标字节所在位置nbytes = str[nbyte_place] # 获取目标字节nbyte_str = encode(nbytes) # 目标字节转换为二进制mbit_place = len(nbyte_str) - mbit # 获取目标bit位置,第一次调试出错点mbits = nbyte_str[mbit_place] # 获取目标bit# bit位翻转+字节二进制还原if mbits == '0':nbyte_str = nbyte_str[:mbit_place] + '1' + nbyte_str[mbit_place+1:]elif mbits == '1':nbyte_str = nbyte_str[:mbit_place] + '0' + nbyte_str[mbit_place+1:]nbyte_str = decode(nbyte_str) # 获取修改后的字节str1 = str[:nbyte_place] + nbyte_str + str[nbyte_place+1:] # 获取修改后的字符串print("str1: " + str1)h2 = hashlib.md5(str1.encode(encoding="utf-8"))h2 = h2.hexdigest()h1 = bin(int(h1, 16))[2:]h2 = bin(int(h2, 16))[2:]if len(h1) != 128:h1 = h1.zfill(128)else:passif len(h2) != 128:h2 = h2.zfill(128)else:passprint("h1: " + h1)print("h2: " + h2)cout_different = cmpcount(h1, h2)print(cout_different)# 测试:python 2 1
if __name__ == "__main__":str, nbyte, mbit = input().split()nbyte = int(nbyte)mbit = int(mbit)avalanche(str, nbyte, mbit)
本题用到的库比第一题少一些,所以就省略了引用库环节,说一下本题的注意事项:
1.字节是按照从低位数排列的,比如 ‘python’ 中的的第一个字节为 ‘n’,第二个字节为 ‘o’,bit位也是按照这样的方式排列的。
2.若是md5加密后的二进制字符串长度不足128位,则需要使用 zfill 函数函数进行补齐,使用方法为str.zfill(lenth),lenth 为需要填充到的位数,本题需要128位,也就是 str.zfill(128)。
3.二进制和字符串之间的相互转换是参照了一位博主的代码,写的很非常nice!看着很简洁就搬到了本程序中。
其他的基本都写在注释里啦,不懂的话欢迎评论区讨论喔~
三、暴力破解MD5
题目描述:编写一个能破解md5的程序
感觉描述的很简洁,我来补充一点点,输入一个字符串,对该字符串进行md5加密,再通过字母、数字、字符的全排列来对照密文,最终得到加密之前的字符串,差不多就是这个意思啦。
1.引入库
代码如下:
from hashlib import md5
from string import ascii_letters, digits, punctuation # 用string模块获得字母、数字和字符
from itertools import permutations # 用于全排列
用法其实很简单的,待会看代码就知道了,注释也有写的,所以就不多赘述啦
2.实现
代码如下:
# 哈希函数的雪崩效应
# author:marxycj
# date:2021-10-29from hashlib import md5
from string import ascii_letters, digits, punctuation # 用string模块获得字母、数字和字符
from itertools import permutations # 用于全排列def brute_md5(md5_value):if len(md5_value) != 32:print("不是有效的md5值")returnelse:allkind = ascii_letters + digits + punctuationfor i in range(5, 10):for j in permutations(allkind, i):md5_test = ''.join(j)md5_testmd5 = md5(md5_test.encode(encoding="utf-8"))md5_testhex = md5_testmd5.hexdigest()if md5_testhex == md5_value:print(md5_test)returnif __name__ == '__main__':md5_value = input()brute_md5(md5_value)
解释一下,allkind就是 字母、数字、字符的组合啦,把三种类型加起来, md5_test用来接收全排列字符串然后进行md5暴力破解测试的,或许叫md5_try合适些,别的也没有啥要注意的啦~
总结
总结:
可能写代码的时候自己写的不快,也不如别人写的好,写的整洁,但是最好还是自己写一遍,毕竟是自己的思路,写完之后再去对照大佬的进行修改,这样或许可以更好地提升自己的代码能力,没有经过思考就照搬代码,能学的东西就比较有限,愿脚踏实地,不骄不躁。
Python 哈希函数与消息认证实验相关推荐
- 密码学数学基础,群,阿贝尔群,阶,双线性对,哈希函数,消息认证码概述
目录 抽象代数基础 群 阿贝尔群(Abelian Group) 阶(Order) 循环群(Cyclic Group) 双线性对 哈希函数H 消息认证码MAC 抽象代数基础 群 定义 群(Group), ...
- Go-哈希函数与消息认证详解(含代码)
目录 哈希函数 简介 历史 特性 安全性 MD族 md4 md5 SHA系列 SHA-1 SHA-2 消息认证 消息认证的目的 消息认证码 认证码与检错码 HMAC的Go实现 crypto/hmac包 ...
- 密码学基础知识(六)Hash函数与消息认证
Hash函数和消息认证 先说Hash 哈希函数,可以将任意长度的消息压缩为某一固定长度的消息摘要函数.一句话,Hash简直了. 当然有逆天的一面就有大缺点,过程不可逆.傻了吧,哈哈. Hash的性质: ...
- Python 哈希函数
1. hashlib 模块实现了许多不同安全散列和消息摘要算法的通用接口.包括FIPS安全哈希算法SHA1,SHA224,SHA256,SHA384和SHA512以及RSA的MD5算法. 如果您需要a ...
- python哈希函数_python hash函数
hash计算可以把任意数据变成一段"摘要",只要这段数据中的任何字节变化都会引起hash值非常大的变化,所以hash值可以用来检查数据有没有被篡改.hash计算的另外一个特性是ha ...
- python编写自定义函数print_triangle(n)_Python 实验8 函数(1).doc
实验8 函数(一) 实验目的: 1. 理解自定义函数过程的定义和调用方法: 2. 掌握自定义函数的定义和调用方法; 3. 理解函数中的参数的作用: 实验内容: 1. 编写一函数Fabonacci(n) ...
- Python哈希函数hashlib
hashlib常用加密方法:md5(), sha1(), sha224(), sha356(), sha384(), sha512()等 结果显示方法: digest(): 返回二进制字符串 h ...
- 哈希函数的原理及应用
哈希(Hash)函数又称为散列函数.杂凑函数.它是一种单向密码体制,即一个从明文到密文的不可逆映射,只有加密过程,没有解密过程. 哈希函数可以将满足要求的任意长度的输入经过变换后得到固定长度的输出.这 ...
- 【学习笔记】密码学入门(2) 单向散列函数,消息认证码,数字签名,证书
[学习笔记]密码学入门(2) 单向散列函数,消息认证码,数字签名,证书 学习笔记 2 – 混合密码系统 在密码学入门(1)中提到了基本的密码形式,对称密码和公钥密码以及混合密码系统. 这一部分将学习到 ...
最新文章
- 解决iptables和vsftpd设置的问题
- 【c++】25.事件驱动的详解
- CSS3构建左侧导航栏
- spark2.0.1 安装配置
- ARM Linux启动过程分析
- OpenCV探索之路(二十五):制作简易的图像标注小工具
- java 删除二维数组中的null_避免在Java中检查Null语句
- Java中文件路径的写法
- 图像语义分割(20) 通过图像合成方法检测训练中未出现的类别未知的物体
- Redis与LRU实现
- 尝试用朴素贝叶斯分析借款信用等级
- 服务器SAS硬盘raid5崩溃lvm丢失的数据恢复过程
- 计算机文件夹里没有显示桌面,桌面上还有文件夹里,有的图标不显示
- 数据链路层(帧)(二)
- WPF教程(二) WPF vs WinForms
- 遗传算法之扇贝的进化(python代码实现)
- Nmap扫描软件分析
- CF1174F Ehab and the Big Finale(交互+剖分)
- Unity中发送邮件
- 苹果又日常被曝做AR眼镜,可消费级市场真的准备好了吗?
热门文章
- 【QNX Hypervisor 2.2 用户手册】1.2 支持的架构、硬件和访客OS
- TrustAsia等CA颁发的TLS/SSL证书的四个pem/crt/key/csr文件区别与说明
- oracle tfa 自启动,oracle TFA 升级实例讲解,tfa实例讲解
- vue实现三级联动,多级联动
- Kindeditor上传本地图片成功后不回显,弹出层也不关闭,解决办法
- EternalBlue(永恒之蓝)漏洞
- 用python分析世界五百强企业数据
- 当遥感图像检测机智起来:全场景AI与遥感的顶峰邂逅
- Linux下安装SEP遇到的问题
- 测试几个LTspice 模型的精度