Я написал следующий алгоритм RSA, который использует два целочисленных ввода для определения интервала, в котором нужно искать простые числа, чтобы начать алгоритм:
import math
import random
import fractions
def get_primes_in_range(low, high):
while True:
try:
if low < 130:
low = int(input("Sorry, the lower bound must be at least 130 to ensure large primes. Please reenter a value for the lower bound of your prime search: "))
except ValueError:
continue
if low < 130:
continue
else:
break
while True:
try:
if high <= low:
high = int(input("Sorry, the higher bound for your prime search must at least be larger than the lower bound. Please reenter a value for the upper bound of your prime search: "))
except ValueError:
continue
if high <= low:
continue
else:
break
primes = []
while len(primes) < 3:
high = (high + 1)
for x in range(low, high+1):
if x > 1:
for n in range(2, x):
if (x % n) == 0:
break
else:
primes.append(x)
return primes
def are_relatively_prime(phi, E):
return fractions.gcd(phi, E) == 1
def generate_key():
primes = get_primes_in_range(low, high)
D = 0
p = random.choice(primes)
primes.remove(p)
q = random.choice(primes)
if p == q:
p = random.choice(primes)
primes.remove(p)
q = random.choice(primes)
N = p * q
phi = (p-1)*(q-1)
E = random.randrange(1, phi)
g = are_relatively_prime(E, phi)
while g != 1:
E = random.randrange(1, phi)
g = are_relatively_prime(E, phi)
for D in range(3, phi, 2):
if D * E % phi == 1:
break
return ((N, E), (N, D))
def power(spisok, b, c):
return [((x**b) % c)for x in spisok]
def encrypt(message, N, E):
message_as_numbers = [ord(i) for i in message]
encrypted_message = power(message_as_numbers, E, N)
return encrypted_message
def decrypt(encrypted_message, N, D):
plain = power(encrypted_message, D, N)
numbers_from_message = [chr(i) for i in plain]
nosmes = [str(i) for i in numbers_from_message]
nosmes = "".join(nosmes)
return nosmes
if __name__ == '__main__':
print "This program will use RSA Encryption to encrypt any message you input."
print "Begin by choosing an interval in which the program should search for primes."
low = int(input("Please enter a lower bound for your prime search: "))
high = int(input("Please enter an upper bound for your prime search: "))
(N, E), (N, D) = generate_key()
print "The encryption keys have been generated."
message = raw_input("Please enter the message you wish to encrypt: ")
print "Your message will now be encrypted by the public key: ", (N, E)
encrypted_message = encrypt(message, N, E)
print "Your message has been encrypted as: "
print(encrypt(message, N, E))
print "Your message will now be decrypted by the private key: ", (N, D)
decrypted_message = decrypt(encrypted_message, N, D)
print "Your decrypted message is: "
print(decrypt(encrypted_message, N, D))
Кажется, это работает, возможно, 9 раз из 10.Однако время от времени при работе в терминале я получаю следующую ошибку:
This program will use RSA Encryption to encrypt any message you input.
Begin by choosing an interval in which the program should search for primes.
Please enter a lower bound for your prime search: 132
Please enter an upper bound for your prime search: 134
The encryption keys have been generated.
Please enter the message you wish to encrypt: hello
Your message will now be encrypted by the public key: (18769, 16141)
Your message has been encrypted as:
[18283L, 12834L, 4908L, 4908L, 11027L]
Your message will now be decrypted by the private key: (18769, 17797)
Traceback (most recent call last):
File "rsaencrtry.py", line 135, in <module>
decrypted_message = decrypt(encrypted_message, N, D)
File "rsaencrtry.py", line 117, in decrypt
numbers_from_message = [chr(i) for i in plain]
ValueError: chr() arg not in range(256)
Я понимаю, что chr () ищет значение от 0 до 255 (коды символов ASCII), ноЯ не понимаю, почему мой алгоритм возвращает значения за пределами этого диапазона.Кажется, это происходит, когда выбранные простые числа близки друг к другу.
Это проблема с моей функцией расшифровки или с выбором простых чисел?