You are on page 1of 16

S[UNIVERSITATEA POLITEHNICA TIMIOARA FACULTATEA DE AUTOMATIC I CALCULATOARE DEPARTAMENTUL DE AUTOMATIC I INFORMATIC APLICAT

Semntura digital RSA


Prezentare general. Model. Exemple. Aplicaii

Studenti Alexandru GHERASIM, anul I Informatic Claudiu ARBANAS anul II Informatica

An universitar 2012-2013 Semestrul II


1

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.

Algoritmul criptografic RSA


Istoric
n criptografie, RSA este un algoritm criptografic cu chei publice, primul algoritm utilizat att pentru criptare, ct i pentru semntura electronic. Algoritmul a fost dezvoltat n 1977 i publicat n 1978 de Ron Rivest, Adi Shamir i Leonard Adleman la MIT i i trage numele de la iniialele numelor celor trei autori. Puterea sa criptografic se bazeaz pe dificultatea problemei factorizrii numerelor ntregi, problem la care se reduce criptanaliza RSA i pentru care toi algoritmii de rezolvare cunoscui au complexitate exponenial. Exist ns cteva metode de criptanaliz care ocolesc factorizarea efectiv, exploatnd maniere eronate de implementare efectiv a schemei de criptare.

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.

Demonstraia formulei de criptare

Formula de decriptare este valabil, deoarece:

i, fiindc i
5

, atunci

i deci se poate scrie:

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.

Atacuri mpotriva RSA


Dei securitatea algoritmului RSA const n legtura dintre acesta i factorizarea ntregilor, el trebuie folosit cu grij n implementri, deoarece, n caz de folosire eronat, sistemele bazate pe RSA pot fi atacate n anumite maniere care ocolesc factorizarea efectiv a modulului, atacatorul ajungnd s obin mesajul clar sau cheia secret.

Atacuri cu text cifrat ales


n cazul atacului cu text cifrat ales, atacatorul dispune de cheia public a entitii atacate (exponentul de criptare e i modulul n), i intercepteaz mesaje cifrate trimise acestuia. Pentru a obine mesajul clar m dintr-un mesaj cifrat c, atacatorul poate proceda, de exemplu, astfel: 1. Calculeaz 2. Trimite entitii atacate spre semnare pe x, obinnd 3. Se observ c 4. Se rezolv ecuaia Atacatorul obine astfel mesajul cifrat. Exist mai multe feluri de atacuri cifrate, dar sunt cteva moduri de aprare mpotriva lor. Unele pot fi evitate dac pur i simplu entitatea protejat cu chei secrete refuz s semneze texte arbitrare trimise de teri. Dac acest lucru nu este posibil (ca de exemplu n cazul unui notar public care trebuie s semneze documente electronice prezentate de persoane strine), atunci atacul poate fi prevenit prin folosirea unei perechi diferite de chei pentru criptare i pentru semntura electronic. De asemenea, este necesar s se foloseasc i un padding aleator pentru mesaj nainte de criptare sau, n cazul semnturii, s nu se semneze mesajul clar, ci un hash al acestuia. Atacul poate fi evitat i dac se impune o anumit structur predefinit mesajelor primite spre semnare.

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.

Exponentul de criptare mic


n unele aplicaii, se folosete un exponent de criptare (public) mic, de exemplu 3, pentru a mri performana, dar i pentru a rezolva unele probleme de securitate. Dac mai multe entiti care comunic folosesc acelai exponent public (dar fiecare are propriul modul i deci propria cheie secret), atunci acelai mesaj trimis mai multor destinatari are urmtoarele valori:

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.

Exponentul de decriptare mic


Dac exponentul de decriptare (cel secret) este mic, pe lng faptul c multe pri din mesaj nu se cripteaz, aa cum s-a artat mai sus, exist un algoritm rapid de gsire a lui d, cunoscnd informaiile e i n. Acest algoritm nu este eficient dac d este de acelai ordin de mrime cu n, deci dac e este mic, acesta fiind unul din motivele pentru care se alege n general e un numr mic, pentru ca d s fie ct mai mare.
8

Generarea semnturii digitale cu algoritmul RSA.


Model
Generarea unei chei publice si private RSA si folosirea acesteie pentru criptarea si decriptarea unor mesaje random: // Coninutul fiierului RSA.java, anexat proiectului import java.math.BigInteger; import java.security.SecureRandom;

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

You might also like