алгоритм RSA на Python

Рейтинг: 2Ответов: 1Опубликовано: 14.02.2023

Доброй ночи всем форумчанам! Мне 14 лет и я начал заниматься программированием на Python ровно полгода назад. В школе взял тему проекта: Шифрование данных с использованием закрытого ключа шифрования. Возникла идея написать шифр RSA. Но вот так не задача, исходные данные, которые необходимо зашифровать не совпадают с полученными после дешифрования. Ломаю голову, не могу понять что сделал не так. Прошу помощи разобраться в чём может быть ошибка (За код сильно не ругайте, писал сам). Делал по алгоритму молодого человека на видео: https://youtu.be/xqPgE-hPIfE. Список b с данными, которые были введены изначально, отличается от дешифрованного списка.

from sympy import randprime, primerange
from math import gcd

def find_two_primes():
    p1 = randprime(1, 100)
    p2 = randprime(1, 100)
    while p1 == p2:
        p2 = randprime(1, 100)
    return (p1, p2)

a = find_two_primes()
print(f'(p, q) = {a}')
mod = a[0] * a[1]
print(f'mod = {mod}')
phi = (a[0] - 1) * (a[1] - 1)
print(f'phi = {phi}')
spisok = list(primerange(1, phi))

for n in spisok:
    if gcd(n, phi) == 1:
        e = n
        break
values = [x for x in range(1, phi + 1)]
d = 0
for elem in values:
    if (int(elem) * e) % phi == 1:
        d += int(elem)
        break
print(f'e = {e}')
print(f'd = {d}')
open_key = (e, mod)
private_key = (d, mod)
print(f'open_key = {open_key}')
print(f'private_key = {private_key}')
b = list(input())
b = [ord(elem) for elem in b]
print(b)
for i in range(len(b)):
    b[i] *= e
    b[i] %= mod
    
print(b)

Ответы

▲ 3Принят

Ну собственно ошибка в одном месте 'b[i] *= e' - вы умножаете элемент на число e, а в алгоритме нужно возводить в степень.

b = list("Hello Wold!")
b = [ord(elem) for elem in b]
print("Before encrypt:")
print(b)
for i in range(len(b)):
   # b[i] *= e  # неправильно
    b[i] = b[i] ** e  # нужно - возведение в степень
    b[i] %= mod
print("After encrypt:")    
print(b)
for i in range(len(b)):
    b[i] = b[i] ** d  # и при дешифровке возведение в степень
    b[i] %= mod
print("After decrypt:")    
print(b)

Ещё замечание - в вашей версии число e - почти всегда будет простым маленьким - 2,3,5,7. Имея эту информацию, злоумышленнику проще будет взломать шифр. Поскольку вы всё равно генерите список простых чисел, выбирайте число из этого списка случайным образом.

# вместо
spisok = list(primerange(1, phi))
for n in spisok:
    if gcd(n, phi) == 1:
        e = n
        break

# выберите случайный элемент из этого списка
n = random.choice(spisok)
while gcd(n, phi) != 1:
    n = random.choice(spisok)
else:
    e = n

Аналогично выбор числа d - вы перебираете числа начиная с 1 - 1,2,3,4 ..., т.е. d это будет наименьшее число, удовлетворяющее условию. Попробуйте наоборот - от (phi - 1) уменьшать.