RSA algoritms ir asimetriskas kriptogrāfijas algoritms. Asimetrisks faktiski nozīmē, ka tas darbojas uz diviem dažādiem taustiņiem, t.i. Publiskā atslēga un Privātā atslēga. Kā norāda nosaukums, publiskā atslēga tiek piešķirta ikvienam, un privātā atslēga tiek turēta privātā veidā.
vai abstraktai klasei var būt konstruktors
Asimetriskās kriptogrāfijas piemērs:
- Klients (piemēram, pārlūkprogramma) nosūta savu publisko atslēgu serverim un pieprasa dažus datus.
- Serveris šifrē datus, izmantojot klienta publisko atslēgu, un nosūta šifrētos datus.
- Klients saņem šos datus un atšifrē tos.
Tā kā tas ir asimetrisks, neviens cits, izņemot pārlūkprogrammu, nevar atšifrēt datus pat tad, ja trešās puses rīcībā ir pārlūkprogrammas publiskā atslēga.
Ideja! RSA ideja ir balstīta uz to, ka lielu veselu skaitli ir grūti faktorizēt. Publiskā atslēga sastāv no diviem skaitļiem, kur viens skaitlis ir divu lielu pirmskaitļu reizinājums. Un privātā atslēga arī ir iegūta no tiem pašiem diviem pirmskaitļiem. Tātad, ja kāds var faktorizēt lielo skaitu, privātā atslēga ir apdraudēta. Tāpēc šifrēšanas stiprums pilnībā ir atkarīgs no atslēgas lieluma, un, ja mēs dubultojam vai trīskāršojam atslēgas lielumu, šifrēšanas stiprums palielinās eksponenciāli. RSA atslēgas parasti var būt 1024 vai 2048 bitus garas, taču eksperti uzskata, ka 1024 bitu atslēgas var tikt salauztas tuvākajā nākotnē. Bet līdz šim tas šķiet neizpildāms uzdevums.
Ļaujiet mums uzzināt RSA algoritma mehānismu:>> Publiskās atslēgas ģenerēšana:
Select two prime no's. Suppose P = 53 and Q = 59. Now First part of the Public key : n = P*Q = 3127. We also need a small exponent say e : But e Must be An integer. Not be a factor of Φ(n). 1 Φ(n) [Φ(n) is discussed below], >> Privātās atslēgas ģenerēšana: mums jāaprēķina Φ(n) : tā, lai Φ(n) = (P-1)(Q-1) tātad, Φ(n) = 3016 Tagad aprēķiniet privāto atslēgu, d : d = (k *Φ(n) + 1) / e kādam veselam skaitlim k Ja k = 2, d vērtība ir 2011. Tagad mēs esam gatavi ar mūsu publisko atslēgu (n = 3127 un e = 3) un privāto atslēgu (d = 2011). ) Tagad mēs šifrēsim HI : pārveidosim burtus par cipariem : H = 8 un I = 9 Tādējādi šifrētie dati c = (89 e ) mod n Tādējādi mūsu šifrētie dati iznāks 1394 Tagad mēs atšifrēsim 1394 : atšifrēti dati = (c d )mod n Tādējādi mūsu šifrētie dati ir 89 8 = H un I = 9, t.i., 'HI'. Zemāk ir parādīts RSA algoritma ieviešana 1. metodei: Mazu ciparu vērtību šifrēšana un atšifrēšana: C++ // C programma RSA asimetriskajam kriptogrāfijas // algoritmam. Demonstrācijai vērtības ir // salīdzinoši mazas, salīdzinot ar praktisko // lietojumprogrammu #include izmantojot namespace std; // Atgriež a un b gcd int gcd(int a, int h) { int temp; kamēr (1) { temp = a % h; if (temp == 0) return h; a = h; h = temp; } } // Kods RSA algoritma demonstrēšanai int main() { // Divi nejauši pirmskaitļi dubultā p = 3; dubultā q = 7; // Publiskās atslēgas pirmā daļa: dubultā n = p * q; // Citas publiskās atslēgas daļas atrašana. // e apzīmē šifrēt dubultā e = 2; dubultā phi = (p - 1) * (q - 1); while (e // e ir jābūt phi līdzprime un // mazākam par phi. if (gcd(e, phi) == 1) break; else e++; } // Privātā atslēga (d apzīmē atšifrēšanu) // izvēloties d tā, lai tas atbilstu // d*e = 1 + k * totient k = 2 // Konstanta vērtība double d = (1 + (k * phi)) / / šifrējamais ziņojums double msg; = 12 printf('Ziņojuma dati = %lf', msg // Šifrēšana c = (msg ^ e) % n double c = pow(msg, e); (' Šifrētie dati = %lf', c // Atšifrēšana m = (c ^ d) % n double m = pow(c, d) m = fmod(m, n); Original Message Sent = %lf', m); java.math.*; importēt java.util.* , double h) { /* * Šī funkcija atgriež gcd jeb lielāko kopējo * dalītāju */ double temp; while (true) { temp = a % h; if (temp == 0) return h; a = h; h = temp; } } public static void main(String[] args) { double p = 3; dubultā q = 7; // Saglabā publiskās atslēgas pirmo daļu: double n = p * q; // Otras publiskās atslēgas daļas atrašana. // double e apzīmē šifrēt double e = 2; dubultā phi = (p - 1) * (q - 1); while (e /* * e ir jābūt līdzsākumam ar phi un * mazākam par phi. */ if (gcd(e, phi) == 1) break; else e++; } int k = 2; // Pastāvīga vērtība double d = (1 + (k * phi)) / e // Šifrējamais ziņojums double msg = 12 System.out.println('Ziņojuma dati = ' + msg; ^ e) % n double c = Math.pow(msg, e = c % n;'Šifrētie dati = ' + c); % n double m = Math.pow(c, d) m = m % n; Python3 # Python RSA asimetriskajam kriptogrāfijas algoritmam # Demonstrēšanai vērtības ir # salīdzinoši mazas, salīdzinot ar praktisko pielietojumu importa math def gcd(a, h): temp = 0 while(1): temp = a % h if (temp ==. 0): atgriešanās h a = h h = temp p = 3 q = 7 n = p*q e = 2 phi = (p-1)*(q-1), savukārt (e # e ir jābūt vienādam ar phi un # mazākam nekā phi if(gcd(e, phi) == 1): break else: e = e+1 # Privātā atslēga (d apzīmē atšifrēšanu) # izvēloties d tā, lai tā atbilstu # d*e = 1 + k * totient. k = 2 d = (1 + (k*phi))/e # Šifrējamais ziņojums msg = 12.0 print('Ziņojuma dati = ', msg) # Šifrēšana c = (msg ^ e) % n c = pow( msg, e) c = math.fmod(c, n) print('Šifrētie dati = ', c) # Atšifrēšana m = (c ^ d) % n m = pow(c, d) m = math.fmod( m, n) print('Original Message Sent = ', m) # Šo kodu ir sagatavojis Pranajs Arora. C# /* * C# programma RSA asimetriskajam kriptogrāfijas algoritmam. * Demonstrēšanai vērtības ir * salīdzinoši mazas, salīdzinot ar praktisko pielietojumu */ izmantojot sistēmu; public class GFG { public static double gcd(double a, double h) { /* * Šī funkcija atgriež gcd jeb lielāko kopējo * dalītāju */ double temp; while (true) { temp = a % h; if (temp == 0) return h; a = h; h = temp; } } static void Main() { double p = 3; dubultā q = 7; // Saglabā publiskās atslēgas pirmo daļu: double n = p * q; // Otras publiskās atslēgas daļas atrašana. // double e apzīmē šifrēt double e = 2; dubultā phi = (p - 1) * (q - 1); while (e /* * e ir jābūt līdzsākumam ar phi un * mazākam par phi. */ if (gcd(e, phi) == 1) break; else e++; } int k = 2; // Pastāvīga vērtība double d = (1 + (k * phi)) / e // Šifrējamais ziņojums double msg = 12 ('Ziņojuma dati = ' + String.Format('{0:F6}); ', msg)); // Šifrēšana c = (msg ^ e) % n double c = Math.Pow(msg, e = c % n) ('Šifrēti dati = ' + String); Format('{0:F6}', c)); // Atšifrēšana m = (c ^ d) % n double m = Math.Pow(c, d) m = m % n; 'Original Message Sent = ' + String.Format('{0:F6}', m)); function gcd(a, h) { /* * Šī funkcija atgriež gcd jeb lielāko * dalītāju */ let temp while (true) { temp = a % h; h = temp } let p = 3 // Saglabā publiskās atslēgas pirmo daļu: let n = p * q; // Otras publiskās atslēgas daļas atrašana. // e apzīmē šifrēt let e = 2; lai phi = (p - 1) * (q - 1); while (e /* * e ir jābūt vienādam ar phi un * mazākam par phi. */ if (gcd(e, phi) == 1) break; else e++; } lai k = 2; // Pastāvīga vērtība let d = (1 + (k * phi)) / e // Šifrējamais ziņojums let msg = 12 console.log('Ziņojuma dati = ' + msg // Šifrēšana c = (msg ^ e; ) % n let c = Math.pow(msg, e) = c % n;'Šifrētie dati = ' + c) = Math.pow(c, d) = m % n; Ziņojums nosūtīts = 12,000000 2. metode: vienkāršu īsziņu, kas satur alfabētu un ciparus, šifrēšana un atšifrēšana, izmantojot to ASCII vērtību: C++ #include izmantojot nosaukumvietas komplektuprime; // kopa būs pirmskaitļu kolekcija, // kur varam atlasīt nejaušus pirmskaitļus p un q int public_key; int privātā_atslēga; int n; // mēs izpildīsim funkciju tikai vienu reizi, lai aizpildītu // pirmskaitļu kopu void primefiller() { // metode, kas tiek izmantota pirmskaitļu kopas aizpildīšanai, ir seive of // eratosthenes(metode pirmskaitļu vākšanai) vektors seive(250, patiess); seive[0] = nepatiess; seive[1] = nepatiess; for (int i = 2; i<250; i++) { for (int j = i * 2; j <250; j += i) { seive[j] = false; } } // filling the prime numbers for (int i = 0; i if (seive[i]) prime.insert(i); } } // picking a random prime number and erasing that prime // number from list because p!=q int pickrandomprime() { int k = rand() % prime.size(); auto it = prime.begin(); while (k--) it++; int ret = *it; prime.erase(it); return ret; } void setkeys() { int prime1 = pickrandomprime(); // first prime number int prime2 = pickrandomprime(); // second prime number // to check the prime numbers selected // cout< n = prime1 * prime2; int fi = (prime1 - 1) * (prime2 - 1); int e = 2; while (1) { if (__gcd(e, fi) == 1) break; e++; } // d = (k*Φ(n) + 1) / e for some integer k public_key = e; int d = 2; while (1) { if ((d * e) % fi == 1) break; d++; } private_key = d; } // to encrypt the given number long long int encrypt(double message) { int e = public_key; long long int encrpyted_text = 1; while (e--) { encrpyted_text *= message; encrpyted_text %= n; } return encrpyted_text; } // to decrypt the given number long long int decrypt(int encrpyted_text) { int d = private_key; long long int decrypted = 1; while (d--) { decrypted *= encrpyted_text; decrypted %= n; } return decrypted; } // first converting each character to its ASCII value and // then encoding it then decoding the number to get the // ASCII and converting it to character vector kodētājs(virknes ziņojums) { vektors forma; // šifrēšanas funkcijas izsaukšana kodēšanas funkcijā priekš (auto& burts : ziņojums) form.push_back(encrypt((int)letter)); atgriešanas veidlapa; } virknes dekodētājs(vektors kodēts) { virkne s; // atšifrēšanas funkcijas izsaukšana dekodēšanas funkcija priekš (auto& num : encoded) s += decrypt(num); atgriešanās s; } int main() { primefiller(); setkeys(); string message = 'Pārbaudes ziņojums'; // tālāk noņemiet komentāru manuālai ievadei // cout<<'enter the message ';getline(cin,message); // calling the encoding function vector kodēts = kodētājs(ziņa); cout<< 'Initial message: ' << message; cout << ' The encoded message(encrypted by public ' 'key) '; for (auto& p : coded) cout << p; cout << ' The decoded message(decrypted by private ' 'key) '; cout << decoder(coded) << endl; return 0; } Java import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Random; public class GFG { private static HashSet prime = new HashSet(); private static Integer public_key = null; private static Integer private_key = null; private static Integer n = null; private static Random random = new Random(); public static void main(String[] args) { primeFiller(); setKeys(); String message = 'Test Message'; // Uncomment below for manual input // System.out.println('Enter the message:'); // message = new Scanner(System.in).nextLine(); List coded = encoder(message); System.out.println('Initial message:'); System.out.println(message); System.out.println( ' The encoded message (encrypted by public key) '); System.out.println( String.join('', coded.stream() .map(Object::toString) .toArray(String[] ::new))); System.out.println( ' The decoded message (decrypted by public key) '); System.out.println(decoder(coded)); } public static void primeFiller() { boolean[] sieve = new boolean[250]; for (int i = 0; i <250; i++) { sieve[i] = true; } sieve[0] = false; sieve[1] = false; for (int i = 2; i <250; i++) { for (int j = i * 2; j <250; j += i) { sieve[j] = false; } } for (int i = 0; i if (sieve[i]) { prime.add(i); } } } public static int pickRandomPrime() { int k = random.nextInt(prime.size()); List primeList = new ArrayList(prime); int ret = primeList.get(k); prime.remove(ret); return ret; } public static void setKeys() { int prime1 = pickRandomPrime(); int prime2 = pickRandomPrime(); n = prime1 * prime2; int fi = (prime1 - 1) * (prime2 - 1); int e = 2; while (true) { if (gcd(e, fi) == 1) { break; } e += 1; } public_key = e; int d = 2; while (true) { if ((d * e) % fi == 1) { break; } d += 1; } private_key = d; } public static int encrypt(int message) { int e = public_key; int encrypted_text = 1; while (e>0) { šifrēts_teksts *= ziņojums; šifrēts_teksts %= n; e - = 1; } atgriež šifrētu_tekstu; } public static int atšifrēt(int šifrētais_teksts) { int d = privātā_atslēga; int atšifrēts = 1; while (d> 0) { atšifrēts *= šifrēts_teksts; atšifrēts %= n; d - = 1; } return atšifrēts; } public static int gcd(int a, int b) { if (b == 0) { return a; } return gcd(b, a % b); } public static List encoder(String message) { Saraksts kodēts = new ArrayList(); for (char letter : message.toCharArray()) { encoded.add(šifrēt((int)burts)); } atgriešanās kodēta; } public static String decoder(Saraksta kodēts) { StringBuilder s = new StringBuilder(); for (int num : kodēts) { s.append((char)decrypt(num)); } return s.toString(); } } Python3 importa izlases importa math # Kopa būs pirmskaitļu kolekcija, # kur mēs varam atlasīt nejaušus pirmskaitļus p un q prime = set() public_key = Nav private_key = Nav n = Nav # Funkciju izpildīsim tikai vienu reizi lai aizpildītu # pirmskaitļu kopu def primefiller(): # Pirmskaitļu kopas aizpildīšanai izmantotā metode ir Sieve of # Eratosthenes (pirmskaitļu vākšanas metode) seive = [True] * 250 seive[0] = False seive[1 ] = Aplams i diapazonā (2, 250): j diapazonā (i * 2, 250, i): seive[j] = False # Pirmskaitļu aizpildīšana i diapazonā (len(seive)): ja seive[i]: prime.add(i) # Izvēloties nejaušu pirmskaitļu un izdzēšot šo pirmo # numuru no saraksta, jo p!=q def pickrandomprime(): globālais pirmskaitlis k = random.randint(0, len(prime) - 1) it = iter(prime) for _ diapazonā(k): next(it) ret = next(it) prime.remove(ret) return ret def setkeys(): globālā publiskā_atslēga, privātā_atslēga, n prime1 = pickrandomprime() # Pirmais pirmskaitlis pirmskaitlis2 = pickrandomprime() # Otrais pirmskaitlis n = pirmskaitlis1 * pirmskaitlis2 fi = (pirmskaitlis1 - 1) * (pirmskaitlis2 - 1) e = 2, kamēr patiess: ja math.gcd(e, fi) == 1: pārtraukums e += 1 # d = (k*Φ(n) + 1) / e kādam veselam skaitlim k publiskā_atslēga = e d = 2, kamēr True: if (d * e) % fi == 1: pārtraukums d += 1 privātā_atslēga = d # Lai šifrētu doto numuru def encrypt(message): globālā publiskā_atslēga, n e = publiskā_atslēga šifrētais_teksts = 1, kamēr e> 0: šifrēts_teksts *= ziņojums šifrēts_teksts %= n e -= 1 return encrypted_text # Lai atšifrētu doto numuru def decrypt( šifrētais_teksts): globālā privātā_atslēga, n d = privātā_atslēga atšifrēta = 1, kamēr d> 0: atšifrēts *= šifrēts_teksts atšifrēts %= n d -= 1 atgriež atšifrēts # Vispirms pārvērš katru rakstzīmi ASCII vērtībā un # pēc tam to kodē, pēc tam atšifrē numuru, lai iegūtu # ASCII un pārveidojot to par rakstzīmju def kodētāju(ziņojumu): encoded = [] # Šifrēšanas funkcijas izsaukšana ziņojumā esošā burta kodēšanas funkcijā: encoded.append(encrypt(ord(burts))) return encoded def decoder(encoded) : s = '' # Atšifrēšanas funkcijas izsaukšana dekodēšanas funkcija num in encoded: s += chr(decrypt(num)) atgriež s if __name__ == '__main__': primefiller() setkeys() message = 'Pārbaudes ziņojums' # Atceliet komentāru zemāk manuālai ievadei # ziņojums = ievade('Ievadiet ziņojumu ') # Kodēšanas funkcijas izsaukšana coded = kodētājs(ziņa) print('Sākotnējais ziņojums:') print(message ) print(' Kodētais ziņojums (šifrēts ar publisko atslēgu) ') print(''.join(str(p) for p in coded)) print(' Atšifrēts ziņojums(atšifrēts ar publisko atslēgu) ') print(''.join(str(p) for p in decoder(coded))) C#, izmantojot sistēmu; izmantojot System.Collections.Generic; publiska klase GFG { privāts statisks HashSet galvenais = jauns HashSet (); privātā statiskā int? publiskā_atslēga = null; privātā statiskā int? privātā_atslēga = null; privātā statiskā int? n = nulle; privāts statisks Nejaušs nejaušs = new Random(); public static void Main() { PrimeFiller(); SetKeys(); string message = 'Pārbaudes ziņojums'; // Atceliet tālāk komentāru manuālai ievadei // Console.WriteLine('Ievadiet ziņojumu:'); // ziņojums = Console.ReadLine(); Saraksts kodēts = Kodētājs(ziņa); Console.WriteLine('Sākotnējais ziņojums:'); Console.WriteLine(ziņa); Console.WriteLine(' Kodētais ziņojums (šifrēts ar publisko atslēgu) '); Console.WriteLine(string.Join('', kodēts)); Console.WriteLine(' Dekodētais ziņojums (atšifrēts ar publisko atslēgu) '); Console.WriteLine(Decoder(coded)); } public static void PrimeFiller() { bool[] sieve = new bool[250]; for (int i = 0; i<250; i++) { sieve[i] = true; } sieve[0] = false; sieve[1] = false; for (int i = 2; i <250; i++) { for (int j = i * 2; j <250; j += i) { sieve[j] = false; } } for (int i = 0; i { if (sieve[i]) { prime.Add(i); } } } public static int PickRandomPrime() { int k = random.Next(0, prime.Count - 1); var enumerator = prime.GetEnumerator(); for (int i = 0; i <= k; i++) { enumerator.MoveNext(); } int ret = enumerator.Current; prime.Remove(ret); return ret; } public static void SetKeys() { int prime1 = PickRandomPrime(); int prime2 = PickRandomPrime(); n = prime1 * prime2; int fi = (prime1 - 1) * (prime2 - 1); int e = 2; while (true) { if (GCD(e, fi) == 1) { break; } e += 1; } public_key = e; int d = 2; while (true) { if ((d * e) % fi == 1) { break; } d += 1; } private_key = d; } public static int Encrypt(int message) { int e = public_key.Value; int encrypted_text = 1; while (e>0) { šifrēts_teksts *= ziņojums; šifrēts_teksts %= n.Vērtība; e - = 1; } atgriež šifrētu_tekstu; } public static int Atšifrēt(int šifrēts_teksts) { int d = privātā_atslēga.Vērtība; int atšifrēts = 1; while (d> 0) { atšifrēts *= šifrēts_teksts; atšifrēts %= n.Vērtība; d - = 1; } return atšifrēts; } public static int GCD(int a, int b) { if (b == 0) { return a; } atgriež GCD(b, a % b); } publiskais statiskais saraksts Kodētājs (virknes ziņojums) { Saraksts kodēts = jauns saraksts (); foreach (zīmes burts ziņojumā) { encoded.Add(Šifrēt((int)burts)); } atgriešanās kodēta; } publiska statiskā virkne Decoder(List kodēts) { virkne s = ''; foreach (int num in encoded) { s += (char)Atšifrēt(num); } return s; } } Izejas sākotnējais ziņojums: Testa ziņojums Kodēts ziņojums (šifrēts ar publisko atslēgu) 863312887135951593413927434912887135951359583051879012887 Atšifrēts ziņojums, izmantojot RSA Impototlement atslēgu, izmantojot RSA Impototlement atslēgu mēs ieviesīsim vienkāršu RSA versiju, izmantojot primitīvas saknes. 1. darbība: atslēgu ģenerēšana Lai sāktu, mums ir jāģenerē divi lieli pirmskaitļi, p un q. Šiem pirmskaitļiem ir jābūt aptuveni vienāda garuma, un to reizinājumam ir jābūt daudz lielākam nekā ziņojumam, kuru vēlamies šifrēt. Mēs varam ģenerēt pirmskaitļus, izmantojot jebkuru primalitātes pārbaudes algoritmu, piemēram, Millera-Rabina testu. Kad mums ir divi pirmskaitļi, mēs varam aprēķināt to reizinājumu n = p*q, kas būs mūsu RSA sistēmas modulis. Tālāk mums jāizvēlas vesels skaitlis e, lai 1 Lai aprēķinātu privātās atslēgas eksponentu d, mums jāatrod vesels skaitlis d, lai d*e = 1 (mod phi(n)). To var izdarīt, izmantojot paplašināto Eiklīda algoritmu. Mūsu publiskā atslēga ir (n, e) un mūsu privātā atslēga ir (n, d). 2. darbība. Šifrēšana Lai šifrētu ziņojumu m, tas ir jāpārvērš par veselu skaitli no 0 līdz n-1. To var izdarīt, izmantojot atgriezenisku kodēšanas shēmu, piemēram, ASCII vai UTF-8. Kad esam ieguvuši ziņojuma veselu skaitļu attēlojumu, mēs aprēķinām šifrēto tekstu c kā c = m^e (mod n). To var efektīvi izdarīt, izmantojot modulāros eksponēšanas algoritmus, piemēram, bināro kāpināšanu. 3. darbība. Atšifrēšana Lai atšifrētu šifrētu tekstu, mēs aprēķinām vienkāršu tekstu m kā m = c^d (mod n). Atkal, mēs varam izmantot modulāros eksponēšanas algoritmus, lai to paveiktu efektīvi. 4. darbība. Piemērs Apskatīsim piemēru, izmantojot mazas vērtības, lai ilustrētu, kā darbojas RSA kriptosistēma. Pieņemsim, ka mēs izvēlamies p = 11 un q = 13, iegūstot n = 143 un phi(n) = 120. Mēs varam izvēlēties e = 7, jo gcd(7, 120) = 1. Izmantojot paplašināto Eiklīda algoritmu, mēs varam aprēķināt d = 103, jo 7*103 = 1 (mod. 120). Mūsu publiskā atslēga ir (143, 7), un mūsu privātā atslēga ir (143, 103). Pieņemsim, ka mēs vēlamies šifrēt ziņojumu HELLO. Mēs varam to pārvērst par veselu skaitli 726564766, izmantojot ASCII kodējumu. Izmantojot publisko atslēgu, mēs aprēķinām šifrēto tekstu kā c = 726564766^7 (mod 143) = 32. Lai atšifrētu šifrētu tekstu, mēs izmantojam privāto atslēgu, lai aprēķinātu m = 32^103 (mod 143) = 726564766, kas ir oriģināls. ziņa. Piemēra kods: C++ #include #include, izmantojot namespace std; // aprēķināt phi(n) dotajam skaitlim n int phi(int n) { int rezultāts = n; for (int i = 2; i<= sqrt(n); i++) { if (n % i == 0) { while (n % i == 0) { n /= i; } result -= result / i; } } if (n>1) { rezultāts -= rezultāts / n; } atgriešanās rezultāts; } // aprēķināt gcd(a, b), izmantojot Eiklīda algoritmu int gcd(int a, int b) { if (b == 0) { return a; } return gcd(b, a % b); } // aprēķina a^b mod m, izmantojot modulāro kāpināšanu int modpow(int a, int b, int m) { int rezultāts = 1; while (b> 0) { if (b & 1) { rezultāts = (rezultāts * a) % m; } a = (a * a) % m; b>>= 1; } atgriešanās rezultāts; } // ģenerēt nejaušu primitīvu sakni modulo n int generētPrimitiveRoot(int n) { int phiN = phi(n); int faktori[phiN], numFactors = 0; int temp = phN; // iegūt visus phi(n) galvenos faktorus, ja (int i = 2; i<= sqrt(temp); i++) { if (temp % i == 0) { factors[numFactors++] = i; while (temp % i == 0) { temp /= i; } } } if (temp>1) { faktori[skaitlisFactors++] = temp; } // pārbaudīt iespējamās primitīvās saknes (int i = 2; i<= n; i++) { bool isRoot = true; for (int j = 0; j if (modpow(i, phiN / factors[j], n) == 1) { isRoot = false; break; } } if (isRoot) { return i; } } return -1; } int main() { int p = 61; int q = 53; int n = p * q; int phiN = (p - 1) * (q - 1); int e = generatePrimitiveRoot(phiN); int d = 0; while ((d * e) % phiN != 1) { d++; } cout << 'Public key: {' << e << ', ' << n << '}' << endl; cout << 'Private key: {' << d << ', ' << n << '}' << endl; int m = 123456; int c = modpow(m, e, n); int decrypted = modpow(c, d, n); cout << 'Original message: ' << m << endl; cout << 'Encrypted message: ' << c << endl; cout << 'Decrypted message: ' << decrypted << endl; return 0; } Output: Public key: {3, 3233} Private key: {2011, 3233} Original message: 123456 Encrypted message: 855 Decrypted message: 123456 Advantages: Security: RSA algorithm is considered to be very secure and is widely used for secure data transmission. Public-key cryptography: RSA algorithm is a public-key cryptography algorithm, which means that it uses two different keys for encryption and decryption. The public key is used to encrypt the data, while the private key is used to decrypt the data. Key exchange: RSA algorithm can be used for secure key exchange, which means that two parties can exchange a secret key without actually sending the key over the network. Digital signatures: RSA algorithm can be used for digital signatures, which means that a sender can sign a message using their private key, and the receiver can verify the signature using the sender’s public key. Speed: The RSA technique is suited for usage in real-time applications since it is quite quick and effective. Widely used: Online banking, e-commerce, and secure communications are just a few fields and applications where the RSA algorithm is extensively developed. Disadvantages: Slow processing speed: RSA algorithm is slower than other encryption algorithms, especially when dealing with large amounts of data. Large key size: RSA algorithm requires large key sizes to be secure, which means that it requires more computational resources and storage space. Vulnerability to side-channel attacks: RSA algorithm is vulnerable to side-channel attacks, which means an attacker can use information leaked through side channels such as power consumption, electromagnetic radiation, and timing analysis to extract the private key. Limited use in some applications: RSA algorithm is not suitable for some applications, such as those that require constant encryption and decryption of large amounts of data, due to its slow processing speed. Complexity: The RSA algorithm is a sophisticated mathematical technique that some individuals may find challenging to comprehend and use. Key Management: The secure administration of the private key is necessary for the RSA algorithm, although in some cases this can be difficult. Vulnerability to Quantum Computing: Quantum computers have the ability to attack the RSA algorithm, potentially decrypting the data.>