本帖最后由 2019-1刘丹丹 于 2022-5-31 11:22 编辑
RSA签名
一.简介
(1)签名就是在这份资料后面增加一段强而有力的证明,以此证明这段信息的发布者和这段信息的有效性完整性。
(2)RSA签名常用的就是将这份信息进行hash,得到一个hash值,再将hash值加密作为签名,后缀在信息的末尾。
(3)哈希的好处:更安全,签名更快,解除了签名长度的限制。
二.具体实现过程
RSA数字签名算法的过程为:A对明文m用解密变换作: (公钥用来加密,私钥用来解密,数字签名是用私钥完成的,所以称为解密变换,这与onu sdk中一致)sº Dk (m)=md mod n,其中d,n为A的私人密钥,只有A才知道它;B收到A的签名后,用A的公钥和加密变换得到明文,因: Ek(s)= Ek(Dk (m))= (md)e mod n,又 deº1 mod j(n)即de=lj(n)+1,根据欧拉定理mj(n)=1 mod n,所以Ek(s)=mlj(n)+1=[mj(n)]em=m mod n。若明文m和签名s一起送给用户B,B可以确信信息确实是A发送的。同时A也不能否认送给这个信息,因为除了A本人外,其他任何人都无法由明文m产生s.因此RSA数字签名方案是可行的。
1 签名算法:签名算法包括消息摘要计算,RSA加密。 (1) 消息摘要计算。 消息在签名前首先通过MD5计算,生成128位的消息摘要 digest。 (2) 对摘要作RSA计算。 用加密算法,采用签名者的私钥加密消息摘要,得到加密后的字符串。加密算法中使用的加密块为01类型。 2 验证签名算法 验证签名算法包括两步:RSA解密得签名者的消息摘要,验证者对原消息计算摘要,比较两个消息摘要。验证签名的过程输入为消息,签名者的公钥,签名;输出为验证的结果,即是否是正确的签名。 (1) RSA解密。 签名实际是加密的字符串。用3.5所述的解密算法,采用签名者的公钥对这个加密的字符串解密。解密的结果应为128位的消息摘要。在解密过程中,若出现得到的加密块的类型不是01,则解密失败。签名不正确。 (2) 消息摘要计算和比较。 验证者对消息用MD5算法重新计算,得到验证者自己的消息摘要。验证者比较解密得到的消息摘要和自己的消息摘要,如果两者相同,则验证成功,可以确认消息的完整性及签名确实为签名者的;否则,验证失败。
三.源代码: - import random
- import hashlib
- def judge(m, s, n, e):
- return m == ''.join([chr(kuaisumi(i, e, n)) for i in s])
- def gcd(a, b):
- if a % b == 0:
- return b
- else:
- return gcd(b, a % b)
- def kuaisumi(a, n, p):
- c = 1
- str = bin(n)[2:][::-1]
- for item in str:
- if item == '1':
- c = (c * a) % p
- a = (a ** 2) % p
- elif item == '0':
- a = (a ** 2) % p
- return c
- def dasushu(w):
- while True:
- number = random.randint(2 ** (w - 1), 2 ** w - 1) | 1
- for i in range(50):
- if not ceshisushu(number):
- break
- if i == 49:
- return number
- def key():
- p = dasushu(512)
- q = dasushu(512)
- n = p * q
- _n = (p - 1) * (q - 1)
- while True:
- e = random.randint(2, _n - 1)
- if gcd(e, _n) == 1:
- break
- d = euclid(e, _n)
- return n, e, d
- def ceshisushu(num):
- s = num - 1
- k = 0
- while s % 2 == 0:
- s = s // 2
- k = k + 1
- a = random.randint(2, num)
- b = kuaisumi(a, s, num)
- if b == 1:
- return True
- for i in range(k):
- if b == num - 1:
- return True
- else:
- b = b * b % num
- return False
- def euclid(x, n):
- r0 = n
- r1 = x % n
- if r1 == 1:
- y = 1
- else:
- s0 = 1
- s1 = 0
- t0 = 0
- t1 = 1
- while r0 % r1 != 0:
- q = r0 // r1
- r = r0 % r1
- r0 = r1
- r1 = r
- s = s0 - q * s1
- s0 = s1
- s1 = s
- t = t0 - q * t1
- t0 = t1
- t1 = t
- if r == 1:
- y = (t + n) % n
- return y
- def sign(m, n, d):
- s = [kuaisumi(ord(i), d, n) for i in m]
- return m, s
- if __name__ == '__main__':
- message = input('请输入原文:').encode('utf-8')
- m = hashlib.sha512(message).hexdigest()
- n, e, d = key()
- m, s = sign(m, n, d)
- print('长度:', len(s))
- with open('sign.txt', 'w') as f:
- f.write(str(s).replace('[', '').replace(']', '').replace(',', '\n').replace(' ', ''))
- print('是否成功?', judge(m, s, n, e))
复制代码
四.运行截图:
|