一、实验目的
1、了解非对称密码体制基本原理
2、掌握编程语言实现非对称加密、解密
二、实验原理
RSA加密算法是一种非对称加密算法,所谓非对称,就是指该算法加密和解密使用不同的密钥,即使用加密密钥进行加密、解密密钥进行解密。在RAS算法中,加密密钥(即公开密钥)是公开信息,而解密密钥(即秘密密钥)是需要保密的。加密算法和解密算法也都是公开的。
公钥 | (E,N) |
私钥 | (D,N) |
密钥对 | (E,D,N) |
加密 | 密文=明文EmodN密文=明文EmodN |
解密 | 明文=密文DmodN明文=密文DmodN |
三、实验代码
import random
from sympy import isprime
class RSA:
def __init__(self):
self.p, self.q = self.generate_random_primes(100)
def is_prime(self, n):
if n <= 3:
return n > 1
elif (n % 2 == 0) or (n % 3 == 0):
return False
i = 5
while i * i <= n:
if (n % i == 0) or (n % (i + 2) == 0):
return False
i += 6
return True
def gcd(self, a, b):
return a if b == 0 else self.gcd(b, a % b)
def lcm(self, a, b):
return a // self.gcd(a, b) * b
def ex_gcd(self, a, b, d, x, y):
if b == 0:
d[0], x[0], y[0] = a, 1, 0
else:
self.ex_gcd(b, a % b, d, y, x)
y[0] -= a // b * x[0]
def quick_power(self, a, b, mod):
res = 1
while b != 0:
if (b & 1) == 1:
res = (res * a) % mod
a = a * a % mod
b >>= 1
return res
def generate_random_primes(self, max_value=100):
primes = []
while len(primes) < 2:
num = random.randint(1, max_value)
if isprime(num):
primes.append(num)
return primes
def generate(self):
lambdan = self.lcm(self.p - 1, self.q - 1)
e = 2
while not self.is_prime(e) or self.gcd(e, lambdan) != 1:
e = random.randint(2, lambdan - 1)
d = [0]
self.ex_gcd(e, lambdan, [0], d, [0])
d = d[0] % lambdan
print("系统随机生成的公钥PU=[e={},n={}]".format(e, self.p * self.q))
print("系统随机生成的私钥PR=[d={},n={}]".format(d, self.p * self.q))
return {
'n': self.p * self.q,
'e': e,
'd': d,
}
def encrypt(self, plaintext, e, n):
return [self.quick_power(ord(char), e, n) for char in plaintext]
def decrypt(self, ciphertext, d, n):
return ''.join(chr(self.quick_power(char, d, n)) for char in ciphertext)
def main():
rsa = RSA()
keys = rsa.generate()
while True:
select = input("输入1加密;输入2解密;输入3退出程序;请输入:\n")
if select == '1':
plaintext = input("输入要加密的明文:\n")
ciphertext = rsa.encrypt(plaintext, keys['e'], keys['n'])
print("密文是:{}".format(ciphertext))
elif select == '2':
encrypted_input = input("输入要解密的密文:\n").strip('[]')
ciphertext = list(map(int, encrypted_input.split(',')))
d, n = map(int, input("请输入私钥PR的d和n值,用逗号分隔:\n").split(','))
plaintext = rsa.decrypt(ciphertext, d, n)
print("明文:{}".format(plaintext))
elif select == '3':
print("退出程序。")
break
else:
print("重新选择!")
if __name__ == '__main__':
main()
四、运行结果