Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import random
- import math
- def miller_rabin(n, t=100): # src: https://pypi.org/project/nprime/#description
- """
- A probabilistic algorithm which determines
- whether a given number (n > 1) is prime or not.
- The miller_rabin tests is repeated t times to get more accurate results.
- Returns a boolean: True if n passes the tests
- """
- if n == 2:
- prime = True # To normalize and make the algorythm works with 2
- else:
- prime = False # All other even number will output false
- # Step 1: Have n-1 = 2^s * m (with m odd, and s number of twos factored)
- d = n - 1
- s = 0
- while d % 2 == 0:
- d //= 2 # d equals to quotient of d divided 2
- s += 1 # s > 1 when n is odd
- for _ in range(0, t):
- # Step 2: test (a^d)^2^r = 1 mod n for all r
- a = random.randrange(1, n)
- for _ in range(0, s):
- x = pow(a, d * pow(2, s), n)
- if x == 1 or x == -1:
- prime = True # Should be true for all a
- else:
- return False # When not true, it's not prime for sure
- return prime # /!\ Probable prime
- def inverso_algoritmo_di_euclide_esteso(a, b):
- x0, x1, y0, y1 = 1, 0, 0, 1
- while b: # Ovvero while b != 0
- q, a, b = a // b, b, a % b
- x0, x1 = x1, x0 - x1 * q
- y0, y1 = y1, y0 - y1 * q
- return x0 # Inverso di a in Z_b
- def p_and_q():
- # Creazione di p e q
- p = random.randint(10**100, 10**101)
- if p % 2 == 0:
- p += 1
- while not miller_rabin(p):
- p += 2
- q = random.randint(10**100, 10**101)
- if q % 2 == 0:
- q += 1
- while not miller_rabin(q):
- q += 2
- return p, q
- def password1():
- # Interfaccia per la scelta della password
- password = input("------------------------------------------------------------------------------------\n"
- "--------------------------------- SCELTA PASSWORD ----------------------------------\n"
- "------------------------------------------------------------------------------------\n"
- "Inserisci una password contenente:\n"
- "- Almeno 10 caratteri\n"
- "- Almeno una lettera maiuscola\n"
- "- Almeno una cifra\n"
- "- Nessun carattere speciale (es.: simboli o lettere accentate/di alfabeti stranieri)\n"
- "------------------------------------------------------------------------------------\n"
- "---------------- Assicurati di essere al riparo da occhi indiscreti ----------------\n"
- "------------------------------------------------------------------------------------\n"
- " ")
- return str(password)
- def password2():
- # Scelta password in caso di password errata
- password = input("Inserisci una password valida: ")
- return password
- def password_control(password):
- # Controllo della password
- special_chars = 0
- upper = 0
- digit = 0
- control = 0
- while control < 4:
- # Fa reinserire la password nel caso abbia meno di 10 caratteri
- if len(password) < 10:
- print("La tua password deve contenere almeno 10 caratteri")
- control = 0
- digit = 0
- upper = 0
- special_chars = 0
- password = password2()
- continue
- else:
- control += 1
- # Fa reinserire la password nel caso contenga caratteri speciali
- for i in range(len(password)):
- if 90 < ord(password[i]) < 65:
- special_chars += 1
- if special_chars > 0:
- print("La tua password non deve contenere nessun carattere speciale")
- control = 0
- digit = 0
- upper = 0
- special_chars = 0
- password = password2()
- continue
- else:
- control += 1
- # Fa reinserire la password nel caso non contenga lettere maiuscole
- for i in range(len(password)):
- if password[i].isupper():
- control += 1
- else:
- upper += 1
- if upper == len(password):
- print("La tua password deve contenere almeno una lettera maiuscola")
- control = 0
- digit = 0
- upper = 0
- password = password2()
- continue
- # Fa reinserire la password nel caso non contenga cifre
- for i in range(len(password)):
- if password[i].isdigit():
- control += 1
- else:
- digit += 1
- if digit == 0:
- print("La tua password deve contenere almeno una cifra")
- control = 0
- digit = 0
- upper = 0
- special_chars = 0
- password = password2()
- continue
- final_password = password
- print("------------------------------------------------------------------------------------\n"
- "----------------------------------Password accettata!-------------------------------\n"
- "------------------------------------------------------------------------------------")
- return str(final_password)
- def user_interface():
- # Interfaccia iniziale
- ui = ("-------------------------------------------------------\n"
- "----------- Digita il numero corrispondente -----------\n"
- "-------------------------------------------------------\n"
- "(1) Registrati (se sei nuovo utente)\n"
- "(2) Accedi alle chiavi pubbliche\n"
- "(3) Accedi alla tua chiave privata (password e nome utente richiesti)\n"
- "-------------------------------------------------------\n"
- " ")
- inp = int(input(ui))
- return inp
- def exit():
- # Interfaccia a fine programma
- exit = int(input("---------------------------------------\n"
- "--- DIgita il numero corrispondente ---\n"
- "---------------------------------------\n"
- " Vuoi uscire?\n"
- " (1) Sì\n"
- " (2) No\n"
- "---------------------------------------\n"
- " "))
- return exit
- def main():
- exitrequest = 2
- while exitrequest == 2:
- # Apre i file di testo contenenti i dati registrati
- p = open("passwords", "a+")
- u = open("usernames", "a+")
- n = open("names", "a+")
- inp = user_interface()
- # Nel caso che l'utente voglia registrarsi:
- if inp == 1:
- # Inserimento nome dell'utente
- name = input("Benvenuto, per prima cosa digita il tuo nome: ")
- # Nel caso che il nome inserito sia già registrato
- n_equal = 1
- while n_equal == 1:
- n_equal = 0
- n.seek(0)
- for line in n:
- if line.rstrip() == name:
- name = input("Esiste già un utente con questo nome, se sei già registrato accedi, altrimenti aggiungi la prima lettera del cognome: ")
- n_equal = 1
- # Inserimento nome utente dell'utente
- username = input("Scegli ora un nome utente: ")
- # Nel caso che il nome utente inserito sia già registrato
- u_equal = 1
- while u_equal == 1:
- u_equal = 0
- u.seek(0)
- for line in u:
- if line.rstrip() == username:
- username = input("Esiste già un utente con questo nome utente, scegline un altro: ")
- u_equal = 1
- # Inserimento e controllo password
- password = password1()
- passwordf = password_control(password)
- # Scrittura di nome, nome utente e password nei file di testo
- n.write(name + "\n")
- u.write(username + "\n")
- p.write(passwordf + "\n")
- # Chiusura file di testo
- n.close()
- u.close()
- p.close()
- # --!-- RSA --!---
- nfile = open("n", "a+")
- dfile = open("d", "a+")
- efile = open("e", "a+")
- p, q = p_and_q()
- print(p)
- print(q)
- n = p * q
- print(n)
- phi_p = p - 1
- phi_q = q - 1
- phi_n = phi_p * phi_q
- # Scelta di e
- e = random.randint(1, phi_n)
- while not math.gcd(e, phi_n) == 1:
- e = random.randint(1, phi_n)
- if e % 2 == 0:
- e += 1
- while not miller_rabin(e):
- e += 2
- print(e)
- # Scelta di d
- d = str(inverso_algoritmo_di_euclide_esteso(e, phi_n))
- print(d)
- nfile.write(str(n) + "\n")
- dfile.write(str(d) + "\n")
- efile.write(str(e) + "\n")
- nfile.close()
- dfile.close()
- efile.close()
- if inp == 2:
- search = input("Di chi vuoi la chiave pubblica? Inserisci il nome, prestando attenzione alla maiuscola: ")
- nfile = open("n", "a+")
- efile = open("e", "a+")
- names = open("names", "a+")
- nlist = list(nfile.read().splitlines())
- elist = list(efile.read().splitlines())
- nameslist = list(names.read().splitlines())
- nfile.seek(0)
- efile.seek(0)
- names.seek(0)
- error = 0
- for i in range(len(nameslist)):
- if nameslist[i] == search:
- print("La chiave pubblica di %s è (n, e) = (%s, %s)" % (nameslist[i], nlist[i], elist[i]))
- error -= 1
- error += 1
- if error != len(nameslist):
- print("%s non esiste nella lista di utenti registrati" % search)
- if inp == 3:
- username = input("Inserisci il tuo nome utente: ")
- password = input("Inserisci la tua password:")
- nfile = open("n", "a+")
- dfile = open("d", "a+")
- usernames = open("usernames", "a+")
- passwords = open("passwords", "a+")
- nlist = list(nfile.read().splitlines())
- dlist = list(dfile.read().splitlines())
- usernameslist = list(usernames.read().splitlines())
- passwordslist = list(passwords.read().splitlines())
- nfile.seek(0)
- dfile.seek(0)
- usernames.seek(0)
- passwords.seek(0)
- for i in range(len(usernameslist)):
- if usernameslist[i] == username:
- if password == passwordslist[i]:
- print("La tua chiave privata è (n, d) = (%s, %s)" % (nlist[i], dlist[i]))
- else:
- print("Mi spiace ma la password e l'username non coincidono, riprova")
- exitrequest = exit()
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement