Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # PublicKeyGenerator_encrypt_decrypt.py
- # Generoidaan kaksi suurta alkulukua p ja q
- # Naiden tulo n= p * q on toinen julkinen avain
- # Avain n maarittaa viestin pituuden ylarajan
- # Jos viesti on muutettu numeroiksi, pituus on numeroiden maaran
- # Toiseksi julkiseksi avaimeksi eksponentti e = 65537
- # Alkuluvun testauksessa kaytetaan Miller-Rabinin menetelmaa,
- # joka on otetty 256GMP:n-lahtoisesti kirjastosta gmpy2.is_prime(n)
- # Selvakielinen viesti salataan julkisilla avaimilla n ja e
- # Salaus puretaan privaatilla purkuavaimella d - yhdessä julkisen avaimen n kanssa
- # Alla oleva ohjelma kayttaa suositeltua eksponentti e = 65537 ja luo avaimen n
- # ja laskee naista purkuavaimen d.
- # Lisaksi ohjelma kysyy kryptattavan viestin ja purkaa sen selvakieliseksi
- # Juhani Kaukoranta 21.8.2019
- import random
- import math
- import time
- import binascii
- import gmpy2
- # GMP -kirjastosta gmpy2 otetaan funktiot is_prime(.) , lcm(.,.) ja invert(.,.)
- # GMP mahdollistaa mielivaltaisen tarkkuuden (arbitrary precision) lukujen kayton
- # ja antaa lukuisia hyodyllisia funktioita
- def generateLargePrime(keysize):
- # Arpoo suuren alkuluvun ja tarkistaa se
- # Millerin-Rabinin menetelmalla
- while True:
- num = random.randrange(2**(keysize-1), 2**(keysize))
- if gmpy2.is_prime(num):
- return num
- # least common multiple gmpy2.lcm(a,b), tarvitaan privaatin purkuavaimen d laskemiseen
- # modular inverse gmpy2.invert(a,b) tarvitaan privaatin purkuavaimen d laskemiseen
- # Luodaan kaksi alkulukua p ja q. Suositeltu eksponentti e=65537 ei saa olla
- # luvun lcm(p-1,q-1) tekijana
- e = 65537 # sertifioitu exponentti joka toimii toisena julkisena avaimena
- print("Ohjelma generoi bittipituudeltaan halutunkokoisen julkisen RSA-avaimen,")
- print("joka on kahden satunnaisen alkuluvun tulo. Alkuluvut ovat kooltaan lahella toisiaan,")
- print("mutteivat liian lahella, jottei niita voitaisi laskea helposti julkisesta avaimesta")
- bittipituus = int(input("Haluttu avaimen n bittipituus, esim 256, 512,1024,2048 "))
- randomjakaja = random.randint(25,30)
- bittipituusp = int(bittipituus/2 - bittipituus/randomjakaja)
- bittipituusq =bittipituus - bittipituusp
- print("[bittipituus,pituusp,pituusq] = ",[bittipituus,bittipituusp,bittipituusq])
- p = generateLargePrime(bittipituusp)
- q = generateLargePrime(bittipituusq)
- moduli = gmpy2.lcm(p-1,q-1)
- while moduli % e == 0: # moduli ei saa olla jaollinen e:lla
- p = generateLargePrime(bittipituusp)
- q = generateLargePrime(bittipituusq)
- moduli = gmpy2.lcm(p-1,q-1)
- print("Alkuluku p = ",p)
- print("Alkuluku q = ",q)
- n = p * q # julkinen avain
- print(" Julkinen avain n = ",n)
- print("Julkisen avaimen n pituus = ",len(str(n))," numeroa ",math.log(n,2)," bittia")
- print("Eksponentti e = ",e)
- # Nyt meilla on eksponentti e ja laskettu kelvollinen n ja moduli
- # Lasketaan e:n ja modulin avulla salauksen privaatti purkuavain d
- d = gmpy2.invert(e,moduli)
- print("Salauksen privaatti purkuavain d = ",d)
- print(" ")
- print(" ****** viestin kirjoitus, salaus, purku selvakieliseksi *****")
- selko_text = input("Kirjoita selvakielinen teksti: ")
- hex_text = binascii.hexlify(selko_text.encode()) # selkoteksti heksadesimaalimuodossa, 2 hex/asciimerkki
- int_text = int(hex_text,16) # selkoteksti kokonaislukuna
- if int_text > n:
- raise Exception("teksti on liian pitka avaimelle n, jaa teksti vaikka lyhyempiin lohkoihin!")
- print("Selvakielinen teksti kokonaislukuna = ",int_text)
- crypt_text = pow(int_text,e,n) # salattu teksti
- print("salattu teksti = ",crypt_text)
- avattu_inttext = pow(crypt_text,d,n)
- print("Avattu teksti kokonaislukuna = ",avattu_inttext)
- avattu_selkotext = binascii.unhexlify(hex(avattu_inttext)[2:]).decode()
- print("Avattu teksti luettavassa muodossa = ",avattu_selkotext)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement