一、RSA算法
1977年由Ron、Adi Shamir和Adleman三个人发明的,于1978年公布。RSA算法是一种分组加密算法,明文和密文在0--n-1之间,n是一个正整数。它是应用最广泛的公钥密码算法。
二、RSA算法描述
明文和密文在0--n-1之间,n是一个正整数
分组大小为为k,<n<=
- 选择两个大素数p和q
- 计算乘积
和
- 选择e(
),使得
- 计算d,满足
(使用欧几里得算法)
- {e,n}为公开密钥,{d,n}为私有密钥
加密算法:
解密算法:
三、代码实现
1.获得密钥(私钥和公钥)
def calculate_key(prime_number1,prime_number2):
"""
计算钥匙
:param prime_number1:
:param prime_number2:
:return:
"""
result_n = prime_number1 * prime_number2
fn = (prime_number1-1)*(prime_number2-1)
public_key= calculate_the_public_key(fn)
private_key=calculate_private_key(fn,public_key)
return public_key,private_key
判断素数
def is_prime_number(prime_number):
"""
判断素数
:param prime_number: 需要判断的数,int
:return: bool值
"""
for i in range(2,prime_number):
if prime_number % i == 0:
print("该数不是素数")
return False
return True
2.计算公钥
def calculate_the_public_key(fn):
"""
计算公钥
:param fn:
:return:
"""
while True:
public_key = random.randint(2, fn)
if calculate_gcd(public_key, fn)[0] == 1:
return public_key
求最大公约数
def calculate_gcd(num1,num2):
"""
求最大公约数(欧几里得算法)
:param num1: 数值1,int
:param num2: 数值2,int
:return: 最大公约数
"""
if num1 < num2 :
num1,num2 = num2,num1
consult_list = []
while True:
if num2 == 0:
del consult_list[0]
return num1,consult_list
else:
result = num1 % num2
consult_list.insert(0,num1 // num2)
num1 = num2
num2 = result
3.计算私钥
def calculate_private_key(fn,public_key):
"""
计算私钥
:param fn: φ(n),int
:param public_key: 公钥e,int
:return:私钥d
"""
list01=calculate_gcd(fn,public_key)[1]
list02 = [1,list01[0]]
for i in range(1,len(list01)):
list02.append(list01[i]*list02[i]+list02[i-1])
if len(list01) % 2 ==0:
return list02[-1]
return fn - list02[-1]
以上是核心算法,下面是人性化操作
4.界面操作
def mean():
"""
菜单
:return:
"""
result_n = 0
while True:
choose = int(input("""
*********欢迎使用RSA加密程序*********
1.获得密钥
2.加密
3.解密
4.退出
************作者:墨非墨************
"""))
if choose == 1: #获得密钥
result_n = get_key()
elif choose == 2:
get_ciphertext (result_n)
elif choose == 3:
get_proclaimed_in_writing (result_n)
elif choose ==4:
print("谢谢使用本程序,欢迎下次光临!")
return False
else:
print("您输入的指令错误,请重新输入")
若运行错误,请将下面代码的位置移动到mean的上面(不包括第4)
get_key
def get_key():
"""
获得密钥
:return:
"""
while True:
int_prime_number01 = int(input("请输入第一个的素数:"))
int_prime_number02 = int(input("请输入第二个的素数:"))
if is_prime_number(int_prime_number01) and is_prime_number(int_prime_number01):
list_key = calculate_key(int_prime_number01, int_prime_number02)
print("公钥{},私钥{}".format(list_key[0], list_key[1]))
return int_prime_number01 * int_prime_number02
else:
print("您输入的不是素数")
continue
对明文或密文合法性判断(0,n-1) is_legality
def is_legality(input_txt,result_n):
"""
验证合法性
:param input_txt:
:param result_n:
:return:
"""
if input_txt < result_n:
return True
return False
get_ ciphertext
def get_ciphertext (result_n):
"""
获得密文
:param result_n:
:return:
"""
while True:
int_public_key = int(input("请输入您的公钥:"))
int_ciphertext = int(input("请输入明文:"))
if is_legality(int_ciphertext, result_n) == False:
print("您输入的明文错误,请重新输入")
continue
ciphertext = int_ciphertext ** int_public_key % result_n
print("密文是{}".format(ciphertext))
if input("是否退出加密,y/n") == "y":
return False
get_proclaimed_in_writing
def get_proclaimed_in_writing (result_n):
"""
获得明文
:param result_n:n
:return:
"""
while True:
int_private_key = int(input("请输入您的私钥:"))
int_proclaimed_writing = int(input("请输入密文:"))
if is_legality(int_proclaimed_writing, result_n) == False:
print("您输入的密文错误,请重新输入")
continue
proclaimed_writing = int_proclaimed_writing ** int_private_key % result_n
print("明文是{}".format(proclaimed_writing))
if input("是否退出解密,y/n") == "y":
return False
4.启动
mean()