编程实现RSA数字签名
一、實驗目的:
理解RSA數(shù)字簽名,并運用編程實現(xiàn)RSA數(shù)字簽名。
二、實驗過程:
1.學習RSA算法及RSA數(shù)字簽名算法流程。
2. RSA數(shù)字簽名原理:當發(fā)送方想要給接收方發(fā)送數(shù)據(jù),并想進行數(shù)字簽名的時候,發(fā)送方只需要利用自己的私鑰,對數(shù)據(jù)進行數(shù)字簽名算法,就可以得到一個新的簽名數(shù)據(jù),這時發(fā)送方需要把自己原來的數(shù)據(jù),以及新得到的簽名數(shù)據(jù)都發(fā)送給接收方,接收方接受到簽名數(shù)據(jù)之后,用發(fā)送方的公鑰對簽名數(shù)據(jù)進行驗證算法,看得出來的數(shù)據(jù)與發(fā)送方發(fā)送過來的數(shù)據(jù)是不是完全一樣的即可。
三、實驗代碼及結(jié)果:
(1)實驗代碼:
import random
import math
#快速冪取模
def power(a, b, n):? #計算a**b mod n
??? if b == 0:
??????? return 1????? #如果b值為0則返回1
??? elif b % 2 == 0:? # 如果二進制b最后一位為0
??????? p = power(a, b / 2, n)????? #遞歸實現(xiàn)
??????? return (p * p) % n??? #取模運算
??? else:
??????? return (a * power(a, b - 1, n)) % n?????? #返回結(jié)果
# 歐幾里得算法求最大公約數(shù)
def gcd(a, b):
??? if a < b:
??????? return gcd(b, a)??????? #如果a小于b,交換兩個數(shù)
??? elif a % b == 0:
??????? return b????? #如果a整除于b則返回b
??? else:
??????? return gcd(b, a % b)??????? #遞歸實現(xiàn)歐幾里得算法
#確定是否是素數(shù)
def isPrime(num):
??? if (num < 2):
??????? return False????????????? #如果num的值小于2返回false
??? else:
??????? i = 2
??????? flag=True
??????? while i < num:? # 如果num能被i整除,說明num不是質(zhì)數(shù)
??????????? if num % i == 0:
??????????????? flag = False???? # 只要num不是質(zhì)數(shù),將flag的值修改為 False
??????????? i += 1
??????? return? flag????? #最后返回flag的值
#生成大素數(shù)函數(shù)
def randPrime(n):
??? Start = 10 ** (n-1) ? #n的值為5,計算開始值10**4
??? End = (10 ** n) - 1? #計算結(jié)束10**5-1
??? while True:
??????? num = random.randint(Start, End)? #返回從start到end之間任意一個數(shù)表示大素數(shù)
??????? if isPrime(num):????? #判斷是否是質(zhì)數(shù),如果是則生成
??????????? return num?????? #返回大素數(shù)的值num
# 擴展的歐幾里得算法,即ab=1 (mod n), 得到a在模n下的乘法逆元b
def Extended_Eulid(a, n):
??? x1, x2, x3 = 1, 0, n
??? y1, y2, y3 = 0, 1, a
??? while y3 != 1 and y3 != 0 and y3 > 0:
??????? Q = math.floor(x3 / y3)
??????? t1, t2, t3 = x1 - Q * y1, x2 - Q * y2, x3 - Q * y3
??????? x1, x2, x3 = y1, y2, y3
??????? y1, y2, y3 = t1, t2, t3
??? if y3 == 0:
??????? return 0
??? if y3 == 1:
??????? if y2 >0:
??????????? return y2
??????? else:
??????????? return n+y2
# 生成公鑰和私鑰
def KeyGen(p, q):????? #分別計算n,e,d的值
??? n = p * q
??? e = random.randint(1, (p - 1) * (q - 1))
??? while gcd(e, (p - 1) * (q - 1)) != 1:?????? #運用歐幾里得算法判斷
??????? e = random.randint(1, (p - 1) * (q - 1))
??? d = Extended_Eulid(e, (p - 1) * (q - 1))
??? return n, e, d
#利用快速冪取模計算簽名
def Sign(x, d, n):
??? s = power(x, d, n)
??? return s
#利用快速冪取模判斷是否有效簽名
def Verify(s, e, n):
??? x_ = power(s, e, n)
??? return x_
#主函數(shù)
if __name__ == '__main__':
??? key_size = 5
??? p = randPrime(key_size)??????? #p與q分別為隨機生成的大素數(shù)
??? q = randPrime(key_size)
??? n, e, d = KeyGen(p, q)??????????? #用p與q生成公鑰和私鑰
??? # 輸入消息
??? x = int(input("請輸入加密信息(必須為整數(shù)): "))
???
??? # 計算簽名
??? s = Sign(x, d, n)
??? # 驗證簽名
??? x_ = Verify(s, e, n)
??? Valid = (x_ == x)
?? ?# 偽造數(shù)據(jù)攻擊
??? s_ = random.randint(1, (p - 1) * (q - 1))
??? m_ = random.randint(1, (p - 1) * (q - 1))
?? ?# 輸出
??? print("私鑰: ")
??? print("N: ", n)
??? print("d: ", d)
??? print("公鑰: ")
??? print("N: ", n)
??? print("e: ", e)
??? print("簽名: ")
??? print("s: ", s)
??? print("驗證m的簽名: ")
??? if Valid:
??????? print("簽名有效")
??? else:
??????? print("簽名無效")
??? print("m'(偽): ", m_)
??? if Verify(m_, s, n) == x:
??????? print("簽名有效")
??? else:
??????? print("簽名無效")
??? print("s' (偽): ", s_)
??? if Verify(x_, s_, n) == x:
??????? print("簽名有效")
??? else:
??????? print("簽名無效")
import randomimport math#快速冪取模def power(a, b, n):? #計算a**b mod nif b == 0:return 1????? #如果b值為0則返回1elif b % 2 == 0:? # 如果二進制b最后一位為0p = power(a, b / 2, n)????? #遞歸實現(xiàn)return (p * p) % n??? #取模運算else:return (a * power(a, b - 1, n)) % n?????? #返回結(jié)果# 歐幾里得算法求最大公約數(shù)def gcd(a, b):if a < b:return gcd(b, a)??????? #如果a小于b,交換兩個數(shù)elif a % b == 0:return b????? #如果a整除于b則返回belse:return gcd(b, a % b)??????? #遞歸實現(xiàn)歐幾里得算法#確定是否是素數(shù)def isPrime(num):if (num < 2):return False????????????? #如果num的值小于2返回falseelse:i = 2flag=Truewhile i < num:? # 如果num能被i整除,說明num不是質(zhì)數(shù)if num % i == 0:flag = False???? # 只要num不是質(zhì)數(shù),將flag的值修改為 Falsei += 1return? flag????? #最后返回flag的值#生成大素數(shù)函數(shù)def randPrime(n):Start = 10 ** (n-1) ? #n的值為5,計算開始值10**4End = (10 ** n) - 1? #計算結(jié)束10**5-1while True:num = random.randint(Start, End)? #返回從start到end之間任意一個數(shù)表示大素數(shù)if isPrime(num):????? #判斷是否是質(zhì)數(shù),如果是則生成return num?????? #返回大素數(shù)的值num# 擴展的歐幾里得算法,即ab=1 (mod n), 得到a在模n下的乘法逆元bdef Extended_Eulid(a, n):x1, x2, x3 = 1, 0, ny1, y2, y3 = 0, 1, awhile y3 != 1 and y3 != 0 and y3 > 0:Q = math.floor(x3 / y3)t1, t2, t3 = x1 - Q * y1, x2 - Q * y2, x3 - Q * y3x1, x2, x3 = y1, y2, y3y1, y2, y3 = t1, t2, t3if y3 == 0:return 0if y3 == 1:if y2 >0:return y2else:return n+y2# 生成公鑰和私鑰def KeyGen(p, q):????? #分別計算n,e,d的值n = p * qe = random.randint(1, (p - 1) * (q - 1))while gcd(e, (p - 1) * (q - 1)) != 1:?????? #運用歐幾里得算法判斷e = random.randint(1, (p - 1) * (q - 1))d = Extended_Eulid(e, (p - 1) * (q - 1))return n, e, d#利用快速冪取模計算簽名def Sign(x, d, n):s = power(x, d, n)return s#利用快速冪取模判斷是否有效簽名def Verify(s, e, n):x_ = power(s, e, n)return x_#主函數(shù)if __name__ == '__main__':key_size = 5p = randPrime(key_size)??????? #p與q分別為隨機生成的大素數(shù)q = randPrime(key_size)n, e, d = KeyGen(p, q)??????????? #用p與q生成公鑰和私鑰# 輸入消息x = int(input("請輸入加密信息(必須為整數(shù)): "))# 計算簽名s = Sign(x, d, n)# 驗證簽名x_ = Verify(s, e, n)Valid = (x_ == x)# 偽造數(shù)據(jù)攻擊s_ = random.randint(1, (p - 1) * (q - 1))m_ = random.randint(1, (p - 1) * (q - 1))# 輸出print("私鑰: ")print("N: ", n)print("d: ", d)print("公鑰: ")print("N: ", n)print("e: ", e)print("簽名: ")print("s: ", s)print("驗證m的簽名: ")if Valid:print("簽名有效")else:print("簽名無效")print("m'(偽): ", m_)if Verify(m_, s, n) == x:print("簽名有效")else:print("簽名無效")print("s' (偽): ", s_)if Verify(x_, s_, n) == x:print("簽名有效")else:print("簽名無效")(2)實驗結(jié)果:
總結(jié)
以上是生活随笔為你收集整理的编程实现RSA数字签名的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 遭遇EBUIITI.SYS,QBNLWV
- 下一篇: 武汉高性能计算大会2022举办,高性能计