CRIPTOGRAFIA E DESCRIPTOGRAFIA RSA:
Alunos: Jhonata Tenório e Jorge Lucas.
Projeto de Criptografia RSA para a nota final da disciplina de Matemárica Discreta, Universidade Federal de Alagoas.
O Método RSA:
RSA (Rivest-Shamir-Adleman) é um dos primeiros sistemas de criptografia de chave pública e é amplamente utilizado para transmissão segura de dados. Neste sistema de criptografia, a chave de encriptação é pública e é diferente da chave de decriptação que é secreta (privada).
(1.0) Abra o seu terminal e digite:
> git clone https://github.com/jhonataT/RSA-PROJECT
(1.1) Acesse o diretório do projeto:
> cd RSA-PROJECT/GUI
(1.2) Execute o arquivo 'script-gui.py':
> python3 script-gui.py
Esolha entre três opções:
Gerar chaves:
def generate_key():
p = gen_prime()
q = gen_prime()
while p == q:
q = gen_prime()
n = p*q
tot_n = phi(p, q)
e = co_primos(tot_n)
➥ Para gerar as chaves, usamos a função 'generate_key()' com o seguinte algoritmo:
I. Usando a função: 'gen_prime()', geramos dois primos de 32 bits ('p' e 'q');
II. Com 'p' e 'q', temos 'n' ('n' = 'p' * 'q');
III. Com a função: 'phi(p, q)', calculamos a função totiente de Euler [ϕ(n) = (p - 1)(q - 1)];
IV. Por último, iremos usar a função 'co_primos(tot_n) para achar um inteiro 'e' tal que 1 < 'e' < 'ϕ(n)', de forma que 'e' e 'ϕ(n)' sejam co-primos.
Encriptar:
def encrypt():
n = int(e7.get()) # PEGANDO O VALOR DE 'n' DA ENTRADA E CONVERTENDO PARA INTEIRO.
e = int(e8.get()) # PEGANDO O VALOR DE 'e' DA ENTRADA E CONVERTENDO PARA INTEIRO.
mensagem = scroll.get('1.0', END) # CAPTURANDO O TEXTO DIGITADO NA SCROLLEDTEXT.
mensagem = mensagem.lower() # DEIXANDO AS LETRAS DA STRING EM MINUSCULO PARA NAO CONFLITAR COM OS DICIONARIOS.
i = 0 # INTEIRO QUE REPRESENTA A POSICAO DA LETRA NA STRING.
error = 0 # INTEIRO AUXILIAR PARA TRATAMENTO DE ERRO.
criptografado = "" # STRING INICIALMENTE VAZIA QUE GUARDA A MENSAGEM CRIPTOGRAFADA.
while i < int(len(mensagem) - 1):
list_int_pow = [] # LISTA AUXILIAR GUARDA A DECOMPOSICAO EM BASE 2 DO EXPOENTE.
try :
x = dic1[mensagem[i]]
except :
error = -1
break
x = dic1[mensagem[i]] # VALOR DE DETERMINADO CARACTER ATRIBUIDO DE ACORDO COM O DICIONARIO.
convert = int_bin(e, "") # CONVERTENDO O VALOR DE E (O EXPOENTE DA POTENCIACAO) EM BINARIO.
generate_list_int(convert, list_int_pow) # ARMAZENANDO EM "LIST_INT POW" OS VALORES NA BASE 2 QUE DECOMPOEM O VALOR 'e'.
y = exp_mod_rap(list_int_pow, x, n, 1, 0) # EXPONENCIACAO MODULAR RAPIDA PARA CRIPTOGRAFAR A MENSAGEM.
criptografado = criptografado + str(y%n) +" " # CONCATENANDO A LETRA CRIPTOGRAFADA NA STRING.
i += 1
➥ Para encriptar a mensagem, usamos a função 'encrypt()' com o seguinte algoritmo:
I. Recebemos 'n', 'e' e a 'mensagem' do usuário, convertendo o conteúdo da 'mensagem' para minúsculo;
II. Percorremos cada caractere da 'mensagem' e relacionamos o caractere com o inteiro correspondente no dicionário (dic1);
III. Convertemos o valor de 'e' para binário e decompomos em base 2, salvando em cada posição de uma lista ('list_int_pow') o valor convertido em inteiro do bit atual;
IV. Usando 'n' e 'e', da chave pública, faremos a exponenciação modular rápida dos valores da lista ('list_int_pow') para resolver [C = T^e (mod n)], onde: C é o caractere criptografado, 'T' é o valor de cada posição da lista, 'e' e 'n' são fornecidos pelo usuário. Dessa forma, cada letra da mensagem será criptografada separadamente.
V. Escrevemos o valor resultante de cada letra, concatenado com espaço " ", no arquivo encrypted.txt
Desencriptar:
def decrypt():
# ENTRADAS DO USUARIO:
e = int(e3.get()) # PEGANDO O VALOR DE 'e' E CONVERTENDO PARA INTEIRO;
p = int(e4.get()) # PEGANDO O VALOR DE 'p'' E CONVERTENDO PARA INTEIRO;
q = int(e5.get()) # PEGANDO O VALOR DE 'q' E CONVERTENDO PARA INTEIRO.
# CALCULO DOS VALORES NECESSARIOS:
n = p * q
tot_n = ((p-1) * (q-1))
d = inversom_m(e, tot_n) # INVERSO MULTIPLICATIVO DE 'e', FUNDAMENTAL PARA A DESCRIPTOGRAFIA.
#manipulação do arquivo de entrada
arquivo_cript = open("../encrypt&decryptFiles/encrypted.txt", "r") # ABRINDO O ARQUIVO CRIPTOGRAFADO INDICADO PELO USUARIO.
mensagem = arquivo_cript.read() # ATRIBUINDO O CONTEUDO DO ARQUIVO CRIPTOGRAFADO A UMA STRING.
lista = mensagem.split(" ") # SEPARANDO CADA LETRA CRIPTOGRAFADA E AS SALVANDO COMO ELEMENTO DE UMA LISTA.
arquivo_cript.close() # FECHANDO O ARQUIVO DE ENTRADA.
#processo de descriptografia
desc = "" # STRING VAZIA QUE VAI ARMAZENAR A MENSAGEM DESCRIPTOGRAFADA.
for item in lista:
#objetos auxiliares
list_int_pow = [] # LISTA AUXILIAR QUE GUARDA DECOMPOSICAO DE BASE 2 DO EXPOENTE
if item == '': # CONDICAO PRA NAO BUGAR NO ULTIMO ITEM DA LISTA QUE SEMPRE VAI SER VAZIO
break
x = int(item) # ATRIBUI A X O INTEIRO DA LISTA QUE VAI SER DESCRIPTOGRAFADO EM UM CARACTER
#r = (x**d) % n
convert = int_bin(d, "") # CONVERTENDO EXPOENTE 'd' EM BINARIO PARA PODER INICIAR A EXPONENCIAÇÃO;
generate_list_int(convert, list_int_pow) # ARMAZENANDO EM UMA LISTA A DECOMPOSIÇÃO DO EXPOENTE EM POTENCIAS DE BASE 2;
y = exp_mod_rap(list_int_pow, x, n, 1, 0) # EXECUTANDO A EXPONENCIACAO MODULAR RAPIDA COM O EXPOENTE 'd'.
desc = desc + dic2[y%n] # CONCATENANDO A MENSAGEM COM O CARACTER DESCRIPTOGRAFADO.
➥ Para desencriptar a mensagem, usamos a função 'decrypt()' com o seguinte algoritmo:
I. Recebemos 'e', 'p' e 'q' do usuário (chaves privadas);
II. Achamos o inverso multiplicativo de 'e', fundamental para a descriptografia;
III. Atribuimos o conteúdo do arquivo CRIPTOGRAFADO a uma string;
IV. Separamos cada letra da mensagem em uma lista;
V. Convertemos o expoente 'd' em binário para poder iniciar a exponenciação;
VI. Armazenamos em uma lista a decomposição do expoente em potências de base 2;
VII. Executamos a exponenciação modular rápida com o expoente 'd', para resolver [T = C^d (mod n)], onde T é o caractere original, C é o caractere criptografado, 'd' é o inverso multiplicativo de 'e' e 'n' é fornecido pelo usuário.
VIII. Depois de resolvido o inverso multiplicativo, resolve-se a exponenciação modular rápida e conseguimos retornar para o valor original T, que está relacioando no dicionário (dic2), então escrevemos no arquivo decrypted.txt cada caractere, formando a frase originalmente criptografada.