区块链技术之数字签名的简单Python代码实现

时间:2024-03-27 19:06:49


假设你要发送一段消息,首先对这段消息进行hash变化(这张图用的是MD‘Message Digest Algorithm 消息摘要算法’方法,代码中用的是sha256 'Secure Hash Algorithm' 方法),以形成摘要,然后对摘要用私匙进行加密,形成数字签名。

最后将   消息+数字签名    一起发出去 

区块链技术之数字签名的简单Python代码实现


接受方进行三个操作,一是对收到的数字签名进行解密,还原出摘要A,二是对收到的消息(也就是报文)进行hash变化,三是比对两个结果,如果一致就说明消息确认是某某所发,并且没有任何的篡改!

区块链技术之数字签名的简单Python代码实现


我参考了别人的代码,稍微进行了一点修改,在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 ̄)′
    



注:以上部分内容来源于网络,如有侵权请联系删除!谢谢