SHA1密码
【题目】1) 实现SHA1 Hash函数算法,具体要求:A. 实现SHA1算法的消息压缩过程,任选一个大小为10M的word文档,并计算其Hash值(注意,计算的是包括文件头等在内的完整文件的Hash函数值,而不仅仅是文件内容的Hash函数值);【实现代码】#!/usr/bin/env python# -*- coding: utf-8 -*-"""Creat
·
【题目】
1) 实现SHA1 Hash函数算法,具体要求:
A. 实现SHA1算法的消息压缩过程,任选一个大小为10M的word文档,并计算其Hash值(注意,计算的是包括文件头等在内的完整文件的Hash函数值,而不仅仅是文件内容的Hash函数值);
【实现代码】
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on Sun Jan 7 15:29:18 2018
@author: HP
"""
from time import clock
#寄存器初始值
A = "0x67452301"
B = "0xefcdab89"
C = "0x98badcfe"
D = "0x10325476"
E = "0xc3d2e1f0"
#Kr
k1 = "0x5a827999" #"0x9979825a"
k2 = "0x6ed9eba1" #"0xa1ebd96e"
k3 = "0x8f1bbcdc" #"0xdcbc1b8f"
k4 = "0xca62c1d6" #"0xd6c162ca"
#4轮非线性函数
Ch = lambda x, y, z: (x&y)^((~x)&z)
Parity = lambda x, y, z: x^y^z #第四轮函数也是Parity
Maj = lambda x, y, z: (x&y)^(x&z)^(y&z)
#左移n位
L = lambda x,n:(((x<<n)|(x>>(32-n)))&(0xffffffff))
#翻转十六进制数的顺序:'0x01234567' => '0x67452301'
def reverse_hex(hex_str):
hex_str = hex_str[2:]
hex_list = []
for i in range(0, len(hex_str), 2):
hex_list.append(hex_str[i:i+2])
hex_list.reverse()
return "0x" + "".join(hex_list)
#SHA1类
class SHA1(object):
def __init__(self, plaintext):
self.plist = ["0x" + hex(x)[2:].rjust(2, "0") for x in plaintext]
self.plength = len(self.plist)*8
self.__fill()
#填充
def __fill(self):
#先填一个0x80(10000000)
self.plist.append("0x80")
#再填充0x00直到还剩8个字节(64)
while (len(self.plist)+8)%64 != 0:
self.plist.append("0x00")
#用消息长度填满剩下的8个字节
p_len = hex(self.plength)[2:].rjust(16, "0")
for i in range(0, len(p_len), 2):
self.plist.append("0x" + p_len[i:i+2])
print(self.plist)
#生成该组消息的80个32位子组
def genM80(self, z):
#起始坐标
start = z*64
#把该组消息分成16个子组, 每组4个字节
result = []
for i in range(start, start+64, 4):
result.append("0x" + "".join((self.plist[i]+self.plist[i+1]+self.plist[i+2]+self.plist[i+3]).split("0x")[1:]))
#产生剩下的64个子组
for i in range(64):
result.append(0)
for i in range(16, 80, 1):
result[i] = hex(L(int(result[i-3], 16)^int(result[i-8], 16)^int(result[i-14], 16)^int(result[i-16], 16), 1))
#对所有子组进行反转并返回
return result
#对每轮进行加密
def fun(self, edcba_list, sfunc, w, k, n):
for i in range(20):
#计算出两个需要计算的结果并赋值给list[0]和list[3]
xx = int(edcba_list[0], 16) + sfunc(int(edcba_list[3], 16), int(edcba_list[2], 16), int(edcba_list[1], 16)) + L(int(edcba_list[4], 16), 5) + int(w[20*n+i], 16) + int(k, 16)
xx = hex(xx&0xffffffff)
edcba_list[0] = xx
edcba_list[3] = hex(L(int(edcba_list[3], 16), 30))
#把整个列表左移1位
x = edcba_list.pop(0)
edcba_list.append(x)
print(edcba_list)
return edcba_list
#加密函数
def encrypt(self):
edcba_list = [E, D, C, B, A]
for i in range(len(self.plist)//64):
#保存寄存器初始值
EE, DD, CC, BB, AA = edcba_list
#进行该组消息的4轮加密
#生成该组消息的80个子分组
w = self.genM80(i)
print(w)
#对每轮20步进行加密
edcba_list = self.fun(edcba_list, Ch, w, k1, 0)
print("------------------------------------------")
edcba_list = self.fun(edcba_list, Parity, w, k2, 1)
print("------------------------------------------")
edcba_list = self.fun(edcba_list, Maj, w, k3, 2)
print("------------------------------------------")
edcba_list = self.fun(edcba_list, Parity, w, k4, 3)
print("------------------------------------------")
output_e = hex((int(EE, 16) + int(edcba_list[0], 16))&0xffffffff)
output_d = hex((int(DD, 16) + int(edcba_list[1], 16))&0xffffffff)
output_c = hex((int(CC, 16) + int(edcba_list[2], 16))&0xffffffff)
output_b = hex((int(BB, 16) + int(edcba_list[3], 16))&0xffffffff)
output_a = hex((int(AA, 16) + int(edcba_list[4], 16))&0xffffffff)
edcba_list = [output_e, output_d, output_c, output_b, output_a]
edcba_list.reverse()
abcde_list = edcba_list
return abcde_list
#显示结果
def show_result(self, abcde_list):
result = ""
for x in abcde_list:
result += x[2:]
return result
if __name__ == "__main__":
print("__________SHA1加密开始______________")
fname = input("please enter the filename: ")
#计时
start = clock()
#读明文
f = open(fname, 'rb')
plaintext = f.read()
f.close()
#加密
sha1 = SHA1(plaintext)
ciphertext = sha1.show_result(sha1.encrypt())
#把密文写回文件
f = open(fname, 'w')
f.write(ciphertext)
f.close()
print("______________加密结束______________")
print("加密结果:%s" %ciphertext)
print("加密时长: %.2f s" %(clock()-start))
更多推荐
已为社区贡献5条内容
所有评论(0)