1.算法介绍
SHA-1(英语:Secure Hash Algorithm 1,中文名:安全散列算法1)是一种密码散列函数,美国国家安全局设计,并由美国国家标准技术研究所(NIST)发布为联邦数据处理标准(FIPS)。SHA-1可以生成一个被称为消息摘要的160位(20字节)散列值,散列值通常的呈现形式为40个十六进制数
2.源码
import math
# 异或算法
def xor_func(a, b):
a = bin(a)[2:]
b = bin(b)[2:]
while len(a) < 32:
a = '0' + a
while len(b) < 32:
b = '0' + b
c = ''
for i in range(0, 32):
if a[i] == b[i]:
c = c + '0'
else:
c = c + '1'
return c
# 与运算
def and_func(a, b):
a = bin(a)[2:]
b = bin(b)[2:]
while len(a) < 32:
a = '0' + a
while len(b) < 32:
b = '0' + b
c = ''
for i in range(0, 32):
if a[i] == '1' and b[i] == '1':
c = c + '1'
else:
c = c + '0'
return c
# ROTL运算
def ROTL_func(a, n):
a = a * 2 ** n
t = int(a / 2 ** 32)
a = a % (2 ** 32) + t
return a
# 非门
def NOT_func(a):
a = bin(a)[2:]
while len(a) < 32:
a = '0' + a
c = ''
for ch in a:
if ch == '0':
c = c + '1'
else:
c = c + '0'
return c
# 步函数算法编写
def step_func(W, list):
A = list[0]
B = list[1]
C = list[2]
D = list[3]
E = list[4]
t = 0
# t=0-19的计算
while t <= 19:
k = 0x5A827999 # K1
if t <= 15:
w = W[t]
else:
w = xor_func(int(W[t - 3], 16), int(W[t - 8], 16)) # t>15后进行新的赋值
w = xor_func(int(w, 2), int(W[t - 14], 16))
w = xor_func(int(w, 2), int(W[t - 16], 16))
temp = w[0]
w = w[1:] + temp
w = hex(int(w, 2))
W.append(w)
t += 1
x = and_func(int(B), int(C)) #
y = NOT_func(B) #
z = and_func(int(y, 2), int(D)) #
a = int(xor_func(int(x, 2), int(z, 2)), 2) # Ch(x,y,z)
e = E
E = D
D = C
C = ROTL_func(int(B), 30) % (2 ** 32)
B = A
A = int(ROTL_func(int(A), 5) + a + int(e) + int(w, 16) + int(k)) % (2 ** 32)
# t=20-39的计算
while t <= 39 and t >= 20:
k = 0x6ED9EBA1 # K2
w = xor_func(int(W[t - 3], 16), int(W[t - 8], 16))
w = xor_func(int(w, 2), int(W[t - 14], 16))
w = xor_func(int(w, 2), int(W[t - 16], 16))
temp = w[0]
w = w[1:] + temp
w = hex(int(w, 2))
W.append(w)
x = int(xor_func(B, C), 2) #
y = int(xor_func(x, D), 2) # Parity(x,y,z)
e = E
E = D
D = C
C = ROTL_func(int(B), 30) % (2 ** 32)
B = A
A = int(ROTL_func(int(A), 5) + y + int(e) + int(w, 16) + int(k)) % (2 ** 32)
t += 1
# t=40-59的计算
while t <= 59 and t >= 40:
k = 0x8f1bbcdc # K3
w = xor_func(int(W[t - 3], 16), int(W[t - 8], 16))
w = xor_func(int(w, 2), int(W[t - 14], 16))
w = xor_func(int(w, 2), int(W[t - 16], 16))
temp = w[0]
w = w[1:] + temp
w = hex(int(w, 2))
W.append(w)
x = int(and_func(B, C), 2) #
y = int(and_func(B, D), 2) #
z = int(and_func(C, D), 2) #
xx = int(xor_func(x, y), 2) #
yy = int(xor_func(xx, z), 2) # Maj(x,y,z)
e = E
E = D
D = C
C = ROTL_func(int(B), 30) % (2 ** 32)
B = A
A = int(ROTL_func(int(A), 5) + yy + int(e) + int(w, 16) + int(k)) % (2 ** 32)
t += 1
# t=60-79的计算
while t <= 79 and t >= 60:
k = 0xca62c1d6 # K4
w = xor_func(int(W[t - 3], 16), int(W[t - 8], 16))
w = xor_func(int(w, 2), int(W[t - 14], 16))
w = xor_func(int(w, 2), int(W[t - 16], 16))
temp = w[0]
w = w[1:] + temp
w = hex(int(w, 2))
W.append(w)
x = int(xor_func(B, C), 2) #
y = int(xor_func(x, D), 2) # Parity(x,y,z)
e = E
E = D
D = C
C = ROTL_func(int(B), 30) % (2 ** 32)
B = A
A = int(ROTL_func(int(A), 5) + y + int(e) + int(w, 16) + int(k)) % (2 ** 32)
t += 1
AA = 0x67452301
BB = 0xEFCDAB89
CC = 0x98BADCFE
DD = 0x10325476
EE = 0xC3D2E1F0
A = (AA + A) % (2 ** 32)
B = (BB + B) % (2 ** 32)
C = (CC + C) % (2 ** 32)
D = (DD + D) % (2 ** 32)
E = (EE + E) % (2 ** 32)
# 给列表传值
list[0] = A
list[1] = B
list[2] = C
list[3] = D
list[4] = E
# 读取需要加密的明文
def main():
A = 0x67452301
B = 0xEFCDAB89
C = 0x98BADCFE
D = 0x10325476
E = 0xC3D2E1F0
list = [A, B, C, D, E]
# 三组测试明文
# m = 'Beijing University of Posts and Telecommunications'
m = 'State Key Laboratory of Networking and Switching'
# m = 'iscbupt'
print('明文为:', m)
W = []
l = len(m)
x = hex(len(m) * 8)
n = 0 # 字符串的读取位置
while 1:
# 长度大于64,即所占字节大于512,需要分段处理
if l > 64:
m = m[n:]
nn = 0
for i in range(1, 64):
if int(nn / 4) * 4 + 4 <= len(m):
p = p + hex(ord(m[nn]))[2:4]
if (nn + 1) % 4 == 0:
W.append(p)
p = ''
nn = nn + 1
step_func(W, list)
n += 64
l -= 64
W = []
# 长度在56与64之间,若要字节在448到512之间,若要其字节满足与512模448同余,还需额外添加使其达到1024字节
elif l >= 56 and l <= 64:
mm = m[n:]
nn = 0
p = ''
j = 0
for i in range(1, 64):
if int(nn / 4) * 4 + 4 <= len(mm):
p = p + hex(ord(mm[nn]))[2:4]
if (nn + 1) % 4 == 0:
W.append(p)
j += 1
p = ''
nn = nn + 1
else:
break
judge = 0
for i in range(0, 4):
if nn < len(mm):
p = p + hex(ord(mm[nn]))[2:4]
nn = nn + 1
else:
if judge == 0:
p = p + '80'
judge = 1
elif judge == 1:
p = p + '00'
W.append(p)
j += 1
if j == 15:
p = '00000000'
W.append(p)
step_func(W, list)
W = []
p = '00000000'
for i in range(0, 14):
W.append(p)
length = len(x) - 2
p = ''
for i in range(0, 16 - length):
p = p + '0'
p = p + x[2:]
W.append(p[0:8])
W.append(p[8:16])
step_func(W, list)
break
# 长度小于56,字节数在0到448之间,需要补全字节使其长度为512
elif l < 56:
mm = m[n:]
nn = 0
p = ''
for i in range(1, 56):
if int(nn / 4) * 4 + 4 <= len(mm):
p = p + hex(ord(mm[nn]))[2:4]
if (nn + 1) % 4 == 0:
W.append(p)
p = ''
nn = nn + 1
else:
break
judge = 0
for i in range(0, 4):
if nn < len(mm):
p = p + hex(ord(mm[nn]))[2:4]
nn = nn + 1
else:
if judge == 0:
p = p + '80'
judge = 1
elif judge == 1:
p = p + '00'
W.append(p)
for i in range(int(len(mm) / 4) + 1, 14):
p = '00000000'
W.append(p)
length = len(x) - 2
p = ''
for i in range(0, 16 - length):
p = p + '0'
p = p + x[2:]
W.append(p[0:8])
W.append(p[8:16])
step_func(W, list)
break
c = hex(list[0])[2:] + hex(list[1])[2:] + hex(list[2])[2:] + hex(list[3])[2:] + hex(list[4])[2:]
print('密文为:', c)
main()
3.运行结果
明文为: State Key Laboratory of Networking and Switching
密文为: ea616117a3115a3caa792813ac5de2743f00b613