Advertisement
herzamos

RSA

Oct 22nd, 2018
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.23 KB | None | 0 0
  1. import random
  2. import math
  3.  
  4.  
  5. def miller_rabin(n, t=100):             # src: https://pypi.org/project/nprime/#description
  6.     """
  7.    A probabilistic algorithm which determines
  8.    whether a given number (n > 1) is prime or not.
  9.    The miller_rabin tests is repeated t times to get more accurate results.
  10.  
  11.    Returns a boolean: True if n passes the tests
  12.  
  13.    """
  14.     if n == 2:
  15.         prime = True  # To normalize and make the algorythm works with 2
  16.     else:
  17.         prime = False  # All other even number will output false
  18.  
  19.     # Step 1: Have n-1 = 2^s * m (with m odd, and s number of twos factored)
  20.     d = n - 1
  21.     s = 0
  22.     while d % 2 == 0:
  23.         d //= 2  # d equals to quotient of d divided 2
  24.         s += 1  # s > 1 when n is odd
  25.  
  26.     for _ in range(0, t):
  27.         #  Step 2: test (a^d)^2^r = 1 mod n for all r
  28.         a = random.randrange(1, n)
  29.         for _ in range(0, s):
  30.             x = pow(a, d * pow(2, s), n)
  31.             if x == 1 or x == -1:
  32.                 prime = True  # Should be true for all a
  33.             else:
  34.                 return False  # When not true, it's not prime for sure
  35.  
  36.     return prime  # /!\ Probable prime
  37.  
  38.  
  39. def inverso_algoritmo_di_euclide_esteso(a, b):
  40.     x0, x1, y0, y1 = 1, 0, 0, 1
  41.     while b:                            # Ovvero while b != 0
  42.         q, a, b = a // b, b, a % b
  43.         x0, x1 = x1, x0 - x1 * q
  44.         y0, y1 = y1, y0 - y1 * q
  45.         return x0                       # Inverso di a in Z_b
  46.    
  47.  
  48. def p_and_q():
  49.     # Creazione di p e q
  50.     p = random.randint(10**100, 10**101)
  51.     if p % 2 == 0:
  52.         p += 1
  53.     while not miller_rabin(p):
  54.         p += 2
  55.     q = random.randint(10**100, 10**101)
  56.     if q % 2 == 0:
  57.         q += 1
  58.     while not miller_rabin(q):
  59.         q += 2      
  60.     return p, q
  61.  
  62.  
  63. def password1():
  64.     # Interfaccia per la scelta della password
  65.     password = input("------------------------------------------------------------------------------------\n"
  66.                      "--------------------------------- SCELTA PASSWORD ----------------------------------\n"
  67.                      "------------------------------------------------------------------------------------\n"
  68.                      "Inserisci una password contenente:\n"
  69.                      "- Almeno 10 caratteri\n"
  70.                      "- Almeno una lettera maiuscola\n"
  71.                      "- Almeno una cifra\n"
  72.                      "- Nessun carattere speciale (es.: simboli o lettere accentate/di alfabeti stranieri)\n"
  73.                      "------------------------------------------------------------------------------------\n"
  74.                      "---------------- Assicurati di essere al riparo da occhi indiscreti ----------------\n"
  75.                      "------------------------------------------------------------------------------------\n"
  76.                      "                                        ")
  77.     return str(password)
  78.  
  79.  
  80. def password2():
  81.     # Scelta password in caso di password errata
  82.     password = input("Inserisci una password valida: ")
  83.     return password
  84.  
  85.  
  86. def password_control(password):
  87.     # Controllo della password
  88.     special_chars = 0
  89.     upper = 0
  90.     digit = 0
  91.     control = 0
  92.     while control < 4:
  93.         # Fa reinserire la password nel caso abbia meno di 10 caratteri
  94.         if len(password) < 10:
  95.             print("La tua password deve contenere almeno 10 caratteri")
  96.             control = 0
  97.             digit = 0
  98.             upper = 0
  99.             special_chars = 0
  100.             password = password2()
  101.             continue
  102.         else:
  103.             control += 1
  104.         # Fa reinserire la password nel caso contenga caratteri speciali
  105.         for i in range(len(password)):
  106.             if 90 < ord(password[i]) < 65:
  107.                 special_chars += 1
  108.         if special_chars > 0:
  109.             print("La tua password non deve contenere nessun carattere speciale")
  110.             control = 0
  111.             digit = 0
  112.             upper = 0
  113.             special_chars = 0
  114.             password = password2()
  115.             continue
  116.         else:
  117.             control += 1
  118.         # Fa reinserire la password nel caso non contenga lettere maiuscole
  119.         for i in range(len(password)):
  120.             if password[i].isupper():
  121.                 control += 1
  122.             else:
  123.                 upper += 1
  124.         if upper == len(password):
  125.             print("La tua password deve contenere almeno una lettera maiuscola")
  126.             control = 0
  127.             digit = 0
  128.             upper = 0
  129.             password = password2()
  130.             continue
  131.         # Fa reinserire la password nel caso non contenga cifre
  132.         for i in range(len(password)):
  133.             if password[i].isdigit():
  134.                 control += 1
  135.             else:
  136.                 digit += 1
  137.         if digit == 0:
  138.             print("La tua password deve contenere almeno una cifra")
  139.             control = 0
  140.             digit = 0
  141.             upper = 0
  142.             special_chars = 0
  143.             password = password2()
  144.             continue
  145.     final_password = password
  146.     print("------------------------------------------------------------------------------------\n"
  147.           "----------------------------------Password accettata!-------------------------------\n"
  148.           "------------------------------------------------------------------------------------")
  149.     return str(final_password)
  150.  
  151.  
  152. def user_interface():
  153.     # Interfaccia iniziale
  154.     ui = ("-------------------------------------------------------\n"
  155.           "----------- Digita il numero corrispondente -----------\n"
  156.           "-------------------------------------------------------\n"
  157.           "(1) Registrati (se sei nuovo utente)\n"
  158.           "(2) Accedi alle chiavi pubbliche\n"
  159.           "(3) Accedi alla tua chiave privata (password e nome utente richiesti)\n"
  160.           "-------------------------------------------------------\n"
  161.           "                        ")
  162.     inp = int(input(ui))
  163.     return inp
  164.  
  165.  
  166. def exit():
  167.     # Interfaccia a fine programma
  168.     exit = int(input("---------------------------------------\n"
  169.                      "--- DIgita il numero corrispondente ---\n"
  170.                      "---------------------------------------\n"
  171.                      "              Vuoi uscire?\n"
  172.                      "               (1) Sì\n"
  173.                      "               (2) No\n"
  174.                      "---------------------------------------\n"
  175.                      "                    "))
  176.     return exit
  177.  
  178.  
  179. def main():
  180.     exitrequest = 2
  181.     while exitrequest == 2:
  182.         # Apre i file di testo contenenti i dati registrati
  183.         p = open("passwords", "a+")
  184.         u = open("usernames", "a+")
  185.         n = open("names", "a+")
  186.         inp = user_interface()
  187.         # Nel caso che l'utente voglia registrarsi:
  188.         if inp == 1:
  189.             # Inserimento nome dell'utente
  190.             name = input("Benvenuto, per prima cosa digita il tuo nome: ")
  191.             # Nel caso che il nome inserito sia già registrato
  192.             n_equal = 1
  193.             while n_equal == 1:
  194.                 n_equal = 0
  195.                 n.seek(0)            
  196.                 for line in n:
  197.                     if line.rstrip() == name:
  198.                         name = input("Esiste già un utente con questo nome, se sei già registrato accedi, altrimenti aggiungi la prima lettera del cognome: ")
  199.                         n_equal = 1
  200.             # Inserimento nome utente dell'utente
  201.             username = input("Scegli ora un nome utente: ")
  202.             # Nel caso che il nome utente inserito sia già registrato
  203.             u_equal = 1
  204.             while u_equal == 1:
  205.                 u_equal = 0
  206.                 u.seek(0)
  207.                 for line in u:
  208.                     if line.rstrip() == username:
  209.                         username = input("Esiste già un utente con questo nome utente, scegline un altro: ")
  210.                         u_equal = 1
  211.             # Inserimento e controllo password
  212.             password = password1()
  213.             passwordf = password_control(password)
  214.             # Scrittura di nome, nome utente e password nei file di testo
  215.             n.write(name + "\n")
  216.             u.write(username + "\n")
  217.             p.write(passwordf + "\n")
  218.             # Chiusura file di testo
  219.             n.close()
  220.             u.close()
  221.             p.close()
  222.             # --!-- RSA --!---
  223.             nfile = open("n", "a+")
  224.             dfile = open("d", "a+")
  225.             efile = open("e", "a+")
  226.             p, q = p_and_q()
  227.             print(p)
  228.             print(q)
  229.             n = p * q
  230.             print(n)
  231.             phi_p = p - 1
  232.             phi_q = q - 1
  233.             phi_n = phi_p * phi_q
  234.             # Scelta di e
  235.             e = random.randint(1, phi_n)
  236.             while not math.gcd(e, phi_n) == 1:
  237.                 e = random.randint(1, phi_n)
  238.                 if e % 2 == 0:
  239.                     e += 1
  240.                 while not miller_rabin(e):
  241.                     e += 2
  242.             print(e)
  243.             # Scelta di d
  244.             d = str(inverso_algoritmo_di_euclide_esteso(e, phi_n))
  245.             print(d)
  246.             nfile.write(str(n) + "\n")
  247.             dfile.write(str(d) + "\n")
  248.             efile.write(str(e) + "\n")
  249.             nfile.close()
  250.             dfile.close()
  251.             efile.close()
  252.         if inp == 2:
  253.             search = input("Di chi vuoi la chiave pubblica? Inserisci il nome, prestando attenzione alla maiuscola: ")
  254.             nfile =  open("n", "a+")
  255.             efile = open("e", "a+")
  256.             names = open("names", "a+")
  257.             nlist = list(nfile.read().splitlines())
  258.             elist = list(efile.read().splitlines())
  259.             nameslist = list(names.read().splitlines())
  260.             nfile.seek(0)
  261.             efile.seek(0)
  262.             names.seek(0)
  263.             error = 0
  264.             for i in range(len(nameslist)):
  265.                 if nameslist[i] == search:
  266.                     print("La chiave pubblica di %s è (n, e) = (%s, %s)" % (nameslist[i], nlist[i], elist[i]))
  267.                     error -= 1
  268.                 error += 1
  269.             if error != len(nameslist):
  270.                 print("%s non esiste nella lista di utenti registrati" % search)
  271.         if inp == 3:
  272.             username = input("Inserisci il tuo nome utente: ")
  273.             password = input("Inserisci la tua password:")
  274.             nfile = open("n", "a+")
  275.             dfile = open("d", "a+")
  276.             usernames = open("usernames", "a+")
  277.             passwords = open("passwords", "a+")
  278.             nlist = list(nfile.read().splitlines())
  279.             dlist = list(dfile.read().splitlines())
  280.             usernameslist = list(usernames.read().splitlines())
  281.             passwordslist = list(passwords.read().splitlines())
  282.             nfile.seek(0)
  283.             dfile.seek(0)
  284.             usernames.seek(0)
  285.             passwords.seek(0)
  286.             for i in range(len(usernameslist)):
  287.                 if usernameslist[i] == username:
  288.                     if password == passwordslist[i]:
  289.                         print("La tua chiave privata è (n, d) = (%s, %s)" % (nlist[i], dlist[i]))
  290.                 else:
  291.                     print("Mi spiace ma la password e l'username non coincidono, riprova")
  292.  
  293.         exitrequest = exit()
  294.        
  295.  
  296. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement