Professional Documents
Culture Documents
Cuprins 1. Introducere. Ce este o semntur digital..................................pagina 3 2. Algoritmul criptografic RSA........................................................pagina 3-6 3. Problema RSA...............................................................................pagina 6-8 4. Generarea semnturii digitale cu algoritmul RSA.Model.........pagina 9-10 5. Exemplu.........................................................................................pagina 10-15 6. Bibliografie....................................................................................pagina 16
Introducere.
Ce este o semntur digital?
O semntur digital este un marcaj electronic de securitate care se poate aduga fiierelor. Permite verificarea editorului fiierului i ajut verificarea dac fiierul nu s-a modificat de cnd a fost semnat digital. Dac fiierul nu are o semntur digital valid, nu exist o modalitate de a se asigura faptul c fiierul este n realitate de la sursa de la care susine c provine sau c nu a fost falsificat (posibil de un virus) de la momentul publicrii. Este mai sigur s evitai deschiderea fiierului dac nu tii cu siguran cine l-a creat i dac este sigur s deschidei coninutul. Nici chiar semntura digital nu asigur c este inofensiv coninutul fiierului. Trebuie s decidei dac avei ncredere n coninutul fiierului bazndu-v pe identitatea editorului i pe locul din care descrcai fiierul.
Funcionare
RSA este un algoritm de criptare pe blocuri. Aceasta nseamn c att textul clar ct i cel cifrat sunt numere ntre 0 i n-1, cu un n ales. Un mesaj de dimensiune mai mare dect este mprit n segmente de lungime corespunztoare, numite blocuri, care sunt cifrate rnd pe rnd.
De asemenea, ca algoritm criptografic cu chei publice, funcioneaz pe baza unei perechi de chei legate matematic ntre ele: o cheie public, cunoscut de toat lumea, i una secret, necunoscut dect de deintorul acesteia.
Generarea cheilor
Perechea de chei se genereaz dup urmtorii pai: 1. Se genereaz dou numere prime, de preferat mari, p i q; 2. Se calculeaz i 3. Se alege un ntreg aleator e, astfel nct cmmdc(e, ) = 1. Perechea (n, e) este cheia public. 4. Folosind algoritmul lui Euclid extins, se calculeaz ntregul d, unicul cu proprietatea c . (n, d) constituie cheia secret.
Decizia cu privire la care dintre e i d este cheia public i care este cea secret este, din punct de vedere matematic, arbitrar, oricare dintre cele dou numere poate juca oricare dintre roluri. n practic ns, pentru a mri viteza de criptare, i ntruct dintre cele dou numere e este cel ales arbitrar, e este cheia public iar valoarea sa este aleas un numr mic, de regul 3, 17 sau 65537 (216+1). Aceasta conduce la un numr minim de nmuliri, deci la o performan sporit, deoarece toate aceste numere au doar dou cifre 1 n reprezentarea lor binar.
Criptarea i decriptarea
Presupunnd c mesajul clar este sub forma unui numr m, mai mic dect n, atunci mesajul cifrat, notat cu c este
unde e este cheia public a destinatarului mesajului. Pentru a decripta mesajul, destinatarul i folosete cheia sa secret d, care are proprietatea foarte important c: Astfel, mesajul clar este recuperat calculnd:
Oricine poate cripta mesaje cu cheia public a destinatarului, dar numai acesta din urm poate decripta, deoarece trebuie s foloseasc cheia sa secret. Algoritmul poate fi folosit i pentru semntura electronic, folosind cheile invers. Dac o entitate cripteaz un mesaj (sau mai degrab un hash al acestuia) cu cheia sa secret i ataeaz rezultatul mesajului su, atunci oricine poate verifica, decriptnd cu cheia public a semnatarului i comparnd rezultatul cu mesajul clar (sau cu hash-ul acestuia), c ntr-adevr acea entitate este autorul mesajului.
Performane n implementri
n general, deoarece se bazeaz pe o operaie destul de costisitoare din punct de vedere al timpului de calcul i al resurselor folosite, i anume exponenierea modulo n, viteza RSA este mult mai mic dect a algoritmilor de criptare cu cheie secret. Bruce Schneier estima, pe baza unor calcule efectuate n anii 1990, c o implementare hardware de RSA este de 1000 de ori mai lent dect o implementare DES, iar n software, RSA este de 100 de ori mai lent. Exist anumite modificri care pot aduce performane sporite, precum alegerea unui exponent de criptare mic, care astfel reduce calculele necesare criptrii, rezolvnd n acelai timp i unele probleme de securitate. De asemenea, operaiile cu cheia secret pot fi accelerate pe baza teoremei chinezeti a resturilor, dac se stocheaz p, q i unele rezultate intermediare, folosite des. Cu toate acestea, mbuntirile nu sunt mari, iar ordinul de mrime al diferenelor de performan fa de implementrile algoritmilor cu cheie secret rmne acelai. De aceea, n sistemele de comunicaie n timp real, n care viteza de criptare i decriptare este esenial (cum ar fi, de exemplu, aplicaiile de streaming video sau audio securizate), RSA se folosete doar la nceputul comunicaiei, pentru a transmite cheia secret de comunicaie, care ulterior este folosit ntr-un algoritm cu cheie secret, cum ar fi 3DES sau AES.
i, fiindc i
5
, atunci
Dar, cum p este prim, i deci prim cu m, conform micii teoreme a lui Fermat, rezult c
Astfel, . Dac p nu este totui prim cu m, atunci nseamn c m este multiplu al lui p, caz trivial n care m este congruent cu 0 modulo p, i deci ridicat la orice putere este congruent cu 0 i deci cu el nsui. Analog i pentru q, De aici, conform teoremei chinezeti a resturilor, deoarece p i q sunt numere prime, rezult c
Problema RSA
Problema decriptrii unui mesaj criptat cu RSA este denumit problema RSA. Aceasta const n obinerea radicalului de ordin e modulo n, unde e i n au proprietatea c n este produsul a dou numere prime mari p i q, iar e este prim cu produsul dintre p-1 i q-1. n acest moment, cea mai eficient metod de a realiza aceasta este descompunerea n factori primi a lui n, i obinerea astfel a cheii secrete d pe baza lui e. Astfel, este demonstrat c dificultatea spargerii unui mesaj criptat cu RSA nu este mai dificil dect problema factorizrii. Nu a fost descoperit nc o alt soluie general a problemei RSA, dar nici nu s-a demonstrat matematic c nu exist o alt soluie. Factorizarea ntregilor prin metodele comune ajut la gsirea soluiilor n timp util doar pentru numere mici. Pentru numere mari, algoritmii de factorizare, cu complexitate exponenial, dau soluia dup foarte mult timp. Cea mai rapid metod de factorizare a ntregilor, algoritmul general al ciurului cmpurilor de numere, are o complexitate de Aici, c este un numr ce ia valori n jur de 1,9 pentru numere de tipul lui n, adic numere cu doi factori primi. Cel mai mare numr factorizat vreodat prin acest algoritm, rulat n anul 2005, de ctre specialiti de la Agenia Federal German pentru Securitatea Tehnologiei
Informaiei, are 200 de cifre zecimale, iar reprezentarea binar a factorilor primi obinui ocup 663 de bii. Cheile de criptare RSA cele mai sigure au lungimi de peste 1024 de bii. Atacul RSA prin metoda forei brute, adic ncercarea fiecrei chei secrete posibile, consum chiar mai mult timp dect factorizarea.
Mesaje necriptate
7
ntruct RSA se bazeaz pe ridicarea la putere (modulo un numr n), exist anumite pri de mesaje care nu sunt criptate, pri rezultate n urma mpririi mesajului pe blocuri. Astfel de mesaje sunt mesajele m cu proprietatea c m=mx (mod n) oricare ar fi x, ca de exemplu m=0, m=1, m=n-1. Numrul exact al acestor mesaje decriptate este , i deci este de minim 9 (deoarece e, p i q sunt impare). Pentru a micora numrul de astfel de pri de mesaj, este util s se foloseasc un exponent public e ct mai mic.
unde ni sunt modulele celor trei destinatari, e este exponentul comun acestora iar m este mesajul trimis tuturor celor trei. Un atacator poate folosi algoritmul lui Gauss pentru a descoperi o soluie mai mic dect n1n2n3 a unui sistem compus din urmtoarele ecuaii:
Aceast soluie este, conform teoremei chinezeti a resturilor, cubul mesajului m. Soluia pentru aceast problem este cea denumit srarea mesajului (din englez salting), adic adugarea unui padding format din numere pseudoaleatoare, padding diferit pentru fiecare expediere a mesajului.
public class RSA { private final static BigInteger one = new BigInteger("1"); private final static SecureRandom random = new SecureRandom(); private BigInteger privateKey; private BigInteger publicKey; private BigInteger modulus; // Generarea cheii publice si cheii private RSA(int N) { BigInteger p = BigInteger.probablePrime(N/2, random); BigInteger q = BigInteger.probablePrime(N/2, random); BigInteger phi = (p.subtract(one)).multiply(q.subtract(one)); modulus = p.multiply(q); publicKey = new BigInteger("65537"); // valoarea utilizata = 2^16 + 1 privateKey = publicKey.modInverse(phi); }
BigInteger encrypt(BigInteger message) { return message.modPow(publicKey, modulus); } BigInteger decrypt(BigInteger encrypted) { return encrypted.modPow(privateKey, modulus); } public String toString() { String s = ""; s += "public = " + publicKey + "\n"; s += "private = " + privateKey + "\n"; s += "modulus = " + modulus;
9
return s; } public static void main(String[] args) { int N = Integer.parseInt(args[0]); RSA key = new RSA(N); System.out.println(key); // Crearea de mesaj random, criptare si decriptare BigInteger message = new BigInteger(N-1, random); // Se creaza mesaj prin convertirea string in integer // String s = "test"; // byte[] bytes = s.getBytes(); // BigInteger message = new BigInteger(s); BigInteger encrypt = key.encrypt(message); BigInteger decrypt = key.decrypt(encrypt); System.out.println("message = " + message); System.out.println("encrpyted = " + encrypt); System.out.println("decrypted = " + decrypt); } }
Exemplu
import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.util.Random; /** * Clasa RSA. * Ofera metode matematice de criptare, decriptare, semnare si verificare. * Daca sunt cunoscute cheile, exista constructori care le folosesc, dar si o metoda * de generare a unei perechi noi de chei. * Toti parametrii sunt BitIntegers, toate return values sunt BitInteger sau * array-uri ale BigInteger. */ public class RSA { /** * Variabila de stocare a exponentului public. */ private BigInteger pubExp = new BigInteger("0");
10
/** * Variabila de stocare a modulului public. */ private BigInteger pubMod = new BigInteger("0"); /** * Variabila de stocare a cheii private. */ private BigInteger privKey = new BigInteger("0"); /** * Lungimea cheii in biti. */ private int keyLength = 0; private static final BigInteger one = new BigInteger("1"); /** * BigIntegers pot fi generati in mod sigur ca primi. Cu cat e mai mare numarul, cu atat e mai incet procesul. Probabilitatea ca un numar generat sa fie prim este: * (1 - 1/2^probabilitate). Prin urmare o valoare 50 inseamna o probabilitate de *0.9999999999999991. */ private static final int certainty = 50; /** * Constructor gol. */ public RSA() { this.pubExp = new BigInteger("0"); this.pubMod = new BigInteger("0"); this.privKey = new BigInteger("0"); }
** * Constructor cu exponent si modul public. * Oricine poate cripta si verifica mesajul cu acesta * * @param publicE - exponentul public. * @param publicM - modulul public. */
11
public RSA(BigInteger publicE, BigInteger publicM) { this.pubExp = publicE; this.pubMod = publicM; this.privKey = new BigInteger("0"); } /** * Constructor with public exponent, public modulus and private key. * This is for the recipient who holds the private key. * * @param publicE the public exponent. * @param publicM the public modulus. * @param privateK the private key. */ public RSA(BigInteger publicE, BigInteger publicM, BigInteger privateK) { this.pubExp = publicE; this.pubMod = publicM; this.privKey = privateK; }
/** * Criptarea cu exponent public si modul public. * Modulul trebuie sa fie mai mare decat mesajul. * * @param transmite mesajul ca BigInteger * @return textul criptat */
public BigInteger encrypt(BigInteger msg) throws RsaException { BigInteger cipher; if (this.pubMod.compareTo(msg) == 1) { cipher = msg.modPow(this.pubExp, this.pubMod); } else { throw new RsaException("Public modulus must be greater than the message!") } return cipher; } /** * Semnarea unui mesaj cu cheia private si modul public. * * @param transmite mesajul ca BigInteger * @return semnatura */ public BigInteger sign(BigInteger msg) throws RsaException {
12
if (this.privKey.equals(new BigInteger("0"))) { throw new RsaException("can't sign a message without private key."); } BigInteger signat; signat = msg.modPow(this.privKey, this.pubMod); return signat; }
/** * Verificarea unui mesaj folosind exponent public si modul public * * @param semnat ca BigInteger. * @return mesajul */ public BigInteger verify(BigInteger signat) { BigInteger veri; veri = signat.modPow(this.pubExp, this.pubMod); return veri; } /** * Decriptarea unui mesaj. Doar posesorul cheii private poate cripta mesajul folosind * cheia privata si modul public * * Return value - m. Daca acest obiect nu are cheia privata, aruncam exceptie. * * * @param criptarea mesajului ca BigInteger. * @return mesajul decriptat ca BigInteger. */ public BigInteger decrypt(BigInteger cipher) throws RsaException { if (this.privKey.equals(new BigInteger("0"))) { throw new RsaException("no decryption without private key."); } BigInteger msg; msg = cipher.modPow(this.privKey, this.pubMod); return msg; } /** *Generarea unei perechi de chei. * Cheie privata, exponent public si modul public se calculeaza si se stocheaza in * privKey, pubExp si pubMod. * * Cheile au lungimi intre 512 si2048 biti. *
13
* @param keyL lungimea cheii este in biti. Daca keyL este zero atunci * o cheie de lungime random este generata in conformitate cu restrictiile de mai sus. * * @return lungimea cheilor publice. */ public int generateKeys(int keyL) { BigInteger one = new BigInteger("1"); Random rand = new Random(); boolean found = false; int keyLength = keyL; if (keyL <= 0) { keyLength = rand.nextInt(49); keyLength = 512 + (keyLength * 32); } this.keyLength = keyLength; BigInteger p = new BigInteger("0"); BigInteger q = new BigInteger("0"); BigInteger p1 = new BigInteger("0"); BigInteger q1 = new BigInteger("0"); BigInteger phi = new BigInteger("0"); BigInteger e = new BigInteger("0");
p = new BigInteger(keyLength/2, certainty, new Random()); q = new BigInteger(keyLength/2+1, certainty, new Random()); do { e = new BigInteger(keyLength, certainty, new Random()); p1 = p.subtract(one); q1 = q.subtract(one); phi = p1.multiply(q1); if ( phi.gcd(e).equals(one) ) { found = true; } } while (!found); BigInteger pubMod = p.multiply(q); BigInteger pubExp = e; // exponent cheie publica BigInteger privateK = pubExp.modInverse(phi); // cheia privata this.privKey = privateK; this.pubExp = pubExp; this.pubMod = pubMod;
return this.keyLength; }
14
/* * Returnarea lungimii cheii. * * returnarea cheii in biti ca si integer. */ public int getKeyLength() { return this.keyLength; } /* * Returnarea cheii private. * * @return un array - la index 0 este exponentul public, la index 1 modulul public. */ public BigInteger[] getPublicKey() { BigInteger[] pubKey = new BigInteger[] {this.pubExp, this.pubMod}; return pubKey; }
/* * Returnarea cheii publice. * * @return un array - la index 0 e exponent public, la index 1 e modul public. */ public BigInteger getPrivateKey() { return this.privKey; }
15
Bibliografie
http://www.wu.ac.at/evoting/en/e-votingtool/countingtool/unittest/rsa.html http://ro.wikipedia.org/wiki/RSA http://technet.microsoft.com/en-us/library/cc962021.aspx http://www.rsa.com/rsalabs/node.asp?id=2221 http://faculty.nps.edu/dedennin/publications/digitalsigsrsa.pdf http://www.drdobbs.com/184404605
16