假设你要发送一段消息,首先对这段消息进行hash变化(这张图用的是MD‘Message Digest Algorithm 消息摘要算法’方法,代码中用的是sha256 'Secure Hash Algorithm' 方法),以形成摘要,然后对摘要用私匙进行加密,形成数字签名。
最后将 消息+数字签名 一起发出去
接受方进行三个操作,一是对收到的数字签名进行解密,还原出摘要A,二是对收到的消息(也就是报文)进行hash变化,三是比对两个结果,如果一致就说明消息确认是某某所发,并且没有任何的篡改!
我参考了别人的代码,稍微进行了一点修改,在Spyder上运行良好:
下面是具体的Python代码实现:
# -*- coding: utf-8 -*-
"""
This is the answer to the homework of information security.
------ Digital Signing
Created on Thu Apr 05 13:56:53 2018
@author: JieZhang
"""
import math
import hashlib as hasher
import datetime as dtime
import random
# 判断是否是素数
def isPrime(n):
if n <= 1:
return False
if n == 2:
return True
for i in range(2,int(math.sqrt(n))+1):
if n % i == 0:
return False
return True
# 找出1000以内的素数,并把其放入一个数组当中
def prime_array():
array = []
for i in range(2,1000):
if isPrime(i):
# print(i)
array.append(i)
return array
"""
# 测试 prime_array() 函数
print(array)
print('素数数组的长度是:{}'.format(len(array)))
"""
# 判断两数是否互质
def isBoth_prime(a,b):
if a < b:
c = a
a = b
b = c
if a == 1 or b ==1:
return True
elif a % b == 0:
return False
else:
c1 = a
a = a % b
b = c1
isBoth_prime(a,b)
return True
"""
# 测试 isBoth_prime()函数
array = []
for i in range(1,50):
for ii in range(1,50):
if isBoth_prime(i,ii):
print(i,ii)
array+=[(i,ii)]
print(array)
"""
# 求 d
def seek(e,s):
d = 0
while True:
d += 1
x = (e * d) % s
if x ==1:
return d
# 加密函数
def Encryption(M,KU):
C = pow(M,KU[0]) % KU[1]
return C
# 解密函数
def decode(C,KR):
M = pow(C,KR[0]) % KR[1]
return M
# 主函数
if __name__ == '__main__':
dict1={'a':0,'b':1,'c':2,'d':3,'e':4,'f':5,'g':6,'h':7,'i':8,'j':9,'k':10,
'l':11,'m':12,'n':13,'o':14,'p':15,'q':16,'r':17,'s':18,'t':19,'u':20,
'v':21,'w':22,'x':23,'y':24,'z':25,'A':26,'B':27,'C':28,'D':29,'E':30,
'F':31,'G':32,'H':33,'I':34,'J':35,'K':36,'L':37,'M':38,'N':39,'O':40,
'P':41,'Q':42,'R':43,'S':44,'T':45,'U':46,'V':47,'W':48,'X':49,'Y':50,
'Z':51,'0':52,'1':53,'2':54,'3':55,'4':56,'5':57,'6':58,'7':59,'8':60,
'9':61,' ':62,'-':63,':':64,'.':65,',':66,'(':67,')':68}
#字典键值转换
dict2 = dict(zip(dict1.values(),dict1))
print('请输入要发送的消息(暂时不支持中文!):')
M = input()
my_hash = hasher.sha256(M).hexdigest()
time = dtime.datetime.now()
print('明文、时间戳及明文的hash值为:')
print('明文 :{}'.format(M))
print('timestamp = {}'.format(time))
print('hash = {}'.format(my_hash))
C = ""
iC = []
print("p,q的取值范围:")
array = prime_array()
print(array)
while True:
p = random.choice(array)
q = random.choice(array)
n = p * q
if n > 100:
break
print('p为{},q为{}'.format(p,q))
s = (p - 1) * (q - 1)
while True:
a = random.choice(range(100))
if isBoth_prime(a,s):
break
e = a
d = seek(e,s)
KU = [e,n]
KR = [d,n]
# 对hash值加密,也就是数字签名
for ch in my_hash:
iC.append(Encryption(dict1[ch],KR))
# 打印至桌面,以看到效果
for i in iC:
C += str(i)
print("加密后密文为:{}".format(C))
print("密文的长度为:{}".format(len(C)))
# 对hash加密后的值进行解密,解签名
receive_hash_encryption = iC
M1 = M
receive_hash = hasher.sha256(M1).hexdigest()
decode_hash = ''
for i in receive_hash_encryption:
decode_hash += dict2[decode(i,KU)]
# 打印至桌面
print('接受到的明文的hash值为 {}'.format(receive_hash))
print("解密后hash为:{}".format(decode_hash))
if receive_hash == decode_hash:
print('确认此消息已验证为JieZhang所发!')
else:
print('此消息有问题!')
结果如图所示:假设JieZhang 哥给 NaXie 姐发消息进行加密(#^.^#),下次我在请他唱歌 φ(0 ̄*)啦啦啦_φ(* ̄0 ̄)′
注:以上部分内容来源于网络,如有侵权请联系删除!谢谢