我用 python 编写了以下 RSA 工具并使其运行,然后我意识到它最初编写的方式会使加密的消息易受频率分析的影响。我一直在升级它,这样它就不会逐个字母地加密,而是将一串 ASCII 值拆分为相等的块并加密块。我慢慢地解决了拆分和重组消息的所有问题,但是一旦我得到解密的消息,19 个字符中有 4 个是错误的,但其余的都是正确的。我使用 89 和 97 作为 p 和 q 值,在测试时得到 e 的 2111、N 的 8633 和 d 的 6335。 Pub Key 是 [2111, 8633] 和 Priv Key [6335, 8633]。要加密和解密的消息是“我要去旅行了!”。解密前的 ASCII 码作为列表拆分为单个字符是 ['073', '109', '032', '103', '111', '105', '110', '103', '032', '111', '110', '032', '097', '032', '084', '114', '105', '112', '033'] 所以我应该在解密端得到相同的列表,但我得到的是 ['073', '100', '399', '103', '111', '105', '110', '103', '032', '111', '110', '032', '010', '702', '084', '114', '105', '112', '033']。如您所见,第二个、第三个、第十三个和第十四个字符不正确,但其余的都是正确的。下面是程序。所有随机的“打印”功能都是我进行故障排除时遗留下来的。我找不到问题,希望得到一些帮助和任何建议或其他错误/您可能会发现。谢谢。
import random
import math
def create_key_set():
p = int(input('Insert prime number for value of p: '))
q = int(input('Insert new prime number for value of q: '))
N = p * q
y = (p-1) * (q-1)
while True:
cop = random.randint(2, (y-1))
gcd = math.gcd(cop, y)
if gcd == 1:
break
e = cop
pubkey = [e, N]
d = pow(e, -1, y)
privkey = [d, N]
print('Public Key is: ', pubkey)
print('Private Key is: ', privkey)
def encrypt_message(e, N, A):
#convert message to list of characters
M = list(A)
#convert list of characters to list of ASCII values
M = list(map(ord, M))
print(M)
#convert list of ASCII values to list of strings
M = list(map(str, M))
#pad list of strings with zeros to make length divisible by 3
M = list(map(lambda x: x.zfill(3), M))
print(M)
#join list into single string
M = ''.join(M)
#pad string with zeros to make length divisible by 4
y = len(M)
z = (math.floor(y / 4) * 4) + 4
M = M.zfill(z)
#split string into list of strings of length 4
o = []
while M:
o.append(M[:4])
M = M[4:]
print(o)
#convert list of strings to list of integers
M = list(map(int, o))
#convert list of integers to list of encrypted integers
M =list(map(lambda x:pow(x, e, N), M))
#convert list of encrypted integers to list of strings
M = list(map(str, M))
#pad list of strings with zeros to make length divisible by 6
M = list(map(lambda x: x.zfill(6), M))
print(M)
#join list of strings into single string
seq = list(map(len, M))
M = ''.join(M)
print('Encrypted message: ', M)
print('Decryption Map: ', seq)
return M, seq
def decrypt_message(d, N, encrypted_message):
#convert encrypted message to string
C = str(encrypted_message)
M = str(C)
#split string into list of strings of length 6
res = []
while M:
res.append(M[:6])
M = M[6:]
print(res)
#convert list of strings to list of integers
M = list(map(int, res))
#convert list of integers to list of decrypted integers
M =list(map(lambda x:pow(x, d, N), M))
#convert list of decrypted integers to list of strings
M = list(map(str, M))
#pad list of strings with zeros to make length divisible by 4
M = list(map(lambda x: x.zfill(4), M))
#join list of strings into single string
M = ''.join(M)
#convert string to list of strings of length 4
res2 = []
while M:
res2.append(M[:4])
M = M[4:]
print(res2)
# convert list of strings to string
M = ''.join(res2)
#convert string to integer
M = int(M)
print(M)
# pad integer with zeros to make length divisible by 3
y = len(str(M))
z = (math.floor(y / 3) * 3) + 3
M = str(M).zfill(z)
# convert integer to list of integers of length 3
res3 = []
while M:
res3.append(M[:3])
M = M[3:]
print(res3)
#convert list of integers to list of characters
M = list(chr(i) for i in M)
#join list of characters into single string
M = "".join(M)
print('Decrypted message: ',M)
def main_menu():
print('Select an option:')
print('1. Create Key Set')
print('2. Encrypt Message')
print('3. Decrypt Message')
option = int(input('Enter your choice: '))
if option == 1:
create_key_set()
main_menu()
elif option == 2:
e = int(input('Insert first number of public key: '))
N = int(input('Insert second number of public key: '))
A = input('Input message to be encrypted: ')
encrypt_message(e, N, A)
main_menu()
elif option == 3:
d = int(input('Insert first number of private key: '))
N = int(input('Insert second number of private key: '))
encrypted_message = input('Insert encrypted message: ')
decrypt_message(d, N, encrypted_message)
main_menu()
else: print('Invalid option, try again.')
if __name__ =='__main__':
main_menu()
我确定它不是写得最好的,因为这是我第一次尝试制作一个完整的程序。另外,请原谅我疯狂使用注释和无意义的变量名。