RSA-algoritme is een asymmetrisch cryptografie-algoritme. Asymmetrisch betekent eigenlijk dat het op twee verschillende toetsen werkt, d.w.z. Publieke sleutel En Prive sleutel. Zoals de naam beschrijft, wordt de publieke sleutel aan iedereen gegeven en wordt de privésleutel privé gehouden.
welke collectie in Java
Een voorbeeld van asymmetrische cryptografie:
- Een client (bijvoorbeeld browser) stuurt zijn publieke sleutel naar de server en vraagt bepaalde gegevens op.
- De server codeert de gegevens met behulp van de openbare sleutel van de client en verzendt de gecodeerde gegevens.
- De client ontvangt deze gegevens en decodeert deze.
Omdat dit asymmetrisch is, kan niemand anders behalve de browser de gegevens ontsleutelen, zelfs als een derde partij over de openbare sleutel van de browser beschikt.
Het idee! Het idee van RSA is gebaseerd op het feit dat het moeilijk is om een groot geheel getal te ontbinden in factoren. De publieke sleutel bestaat uit twee getallen, waarbij één getal een vermenigvuldiging is van twee grote priemgetallen. En de privésleutel is ook afgeleid van dezelfde twee priemgetallen. Dus als iemand het grote getal kan ontbinden in factoren, komt de privésleutel in gevaar. Daarom hangt de sterkte van de versleuteling volledig af van de sleutelgrootte en als we de sleutelgrootte verdubbelen of verdrievoudigen, neemt de sterkte van de versleuteling exponentieel toe. RSA-sleutels kunnen doorgaans 1024 of 2048 bits lang zijn, maar experts zijn van mening dat 1024-bits sleutels in de nabije toekomst kapot kunnen gaan. Maar tot nu toe lijkt het een onhaalbare opgave.
Laten we het mechanisme achter het RSA-algoritme leren kennen:>> Publieke sleutel genereren:
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ésleutel genereren: We moeten Φ(n) berekenen: Zo dat Φ(n) = (P-1)(Q-1) dus, Φ(n) = 3016 Bereken nu de privésleutel, d: d = (k *Φ(n) + 1) / e voor een geheel getal k Voor k = 2 is de waarde van d 2011. Nu zijn we klaar met onze – Publieke Sleutel ( n = 3127 en e = 3) en Private Key(d = 2011 ) Nu gaan we HI coderen: letters omzetten in cijfers: H = 8 en I = 9 Dus gecodeerde gegevens c = (89 e) mod n Dus onze gecodeerde gegevens blijken 1394 te zijn. Nu gaan we 1394 decoderen: gedecodeerde gegevens = (c d )mod n Onze gecodeerde gegevens komen dus uit op 89 8 = H en I = 9, d.w.z. 'HI'. Hieronder vindt u de implementatie van het RSA-algoritme voor methode 1: Kleine numerieke waarden coderen en decoderen: C++ // C-programma voor RSA asymmetrisch cryptografisch // algoritme. Voor demonstratie zijn waarden // relatief klein vergeleken met praktisch // application #include met behulp van naamruimte std; // Retourneert ggd van a en b int ggd(int a, int h) { int temp; terwijl (1) { temp = a% h; als (temp == 0) h retourneert; a = h; h = temperatuur; } } // Code om het RSA-algoritme te demonstreren int main() {// Twee willekeurige priemgetallen verdubbelen p = 3; dubbele q = 7; // Eerste deel van de publieke sleutel: dubbel n = p * q; // Ander deel van de publieke sleutel zoeken. // e staat voor encrypt double e = 2; dubbele phi = (p - 1) * (q - 1); while (e // e moet co-prime zijn voor phi en // kleiner dan phi. if (gcd(e, phi) == 1) break; else e++; } // Privésleutel (d staat voor decrypt) // d zo kiezen dat het voldoet aan // d*e = 1 + k * totient int k = 2; // Een constante waarde double d = (1 + (k * phi)) / e // Te versleutelen bericht double msg = 12; printf('Berichtgegevens = %lf', msg); // Codering c = (msg ^ e) % n dubbel c = pow(msg, e); ('
Gecodeerde gegevens = %lf', c // Decryptie m = (c ^ d) % n dubbel m = pow(c, d);
Origineel bericht verzonden = %lf', m); return 0; } // Deze code is bijgedragen door Akash Sharan /*pakket wat dan ook //schrijf hier geen pakketnaam */ import java.io.*; java.math.*; import java.util.*; /* * Java-programma voor RSA asymmetrisch cryptografisch algoritme * Ter demonstratie: de waarden zijn * relatief klein in vergelijking met de praktische toepassing */ public class GFG { public static double gcd(double a). , double h) { /* * Deze functie retourneert de ggd of de grootste gemene * deler */ double temp; terwijl (waar) { temp = a% h; als (temp == 0) h retourneert; a = h; h = temperatuur; } } public static void main(String[] args) { dubbele p = 3; dubbele q = 7; // Slaat het eerste deel van de publieke sleutel op: dubbel n = p * q; // Het andere deel van de publieke sleutel vinden. // dubbele e staat voor versleutelen dubbele e = 2; dubbele phi = (p - 1) * (q - 1); while (e /* * e moet co-prime zijn voor phi en * kleiner dan phi. */ if (ggd(e, phi) == 1) break; else e++; } int k = 2; // Een constante waarde double d = (1 + (k * phi)) / e; // Te versleutelen bericht double msg = 12; System.out.println('Berichtgegevens = ' + msg); ^ e) % n double c = Math.pow(msg, e); c = c % n; System.out.println('Gecodeerde gegevens = ' + c // Decodering m = (c ^ d) % n double m = Math.pow(c, d); m = m % n; System.out.println('Origineel bericht verzonden = ' + m); Python3 # Python voor RSA asymmetrisch cryptografisch algoritme # Ter demonstratie zijn de waarden # relatief klein vergeleken met praktische toepassingen import math def ggd(a, h): temp = 0 while(1): temp = a % h if (temp == 0): return h a = h h = temp p = 3 q = 7 n = p*q e = 2 phi = (p-1)*(q-1) terwijl (e # e co-prime moet zijn met phi en # kleiner dan phi if(ggd(e, phi) == 1): break else: e = e+1 # Privésleutel (d staat voor decoderen) # d zo kiezen dat deze voldoet aan # d*e = 1 + k * totient. k = 2 d = (1 + (k*phi))/e # Te versleutelen bericht msg = 12.0 print('Berichtgegevens = ', msg) # Encryptie c = (msg ^ e) % n c = pow( msg, e) c = math.fmod(c, n) print('Gecodeerde gegevens = ', c) # Decodering m = (c ^ d) % n m = pow(c, d) m = math.fmod( m, n) print('Origineel bericht verzonden = ', m) # Deze code is bijgedragen door Pranay Arora. C# /* * C# programma voor RSA asymmetrisch cryptografisch algoritme. * Ter demonstratie zijn de waarden * relatief klein in vergelijking met praktische toepassing */ met behulp van System; public class GFG { public static double ggd(double a, double h) { /* * Deze functie retourneert de ggd of de grootste gemene * deler */ double temp; terwijl (waar) { temp = a% h; als (temp == 0) h retourneert; a = h; h = temperatuur; } } statische leegte Main() { dubbele p = 3; dubbele q = 7; // Slaat het eerste deel van de publieke sleutel op: dubbel n = p * q; // Het andere deel van de publieke sleutel vinden. // dubbele e staat voor versleutelen dubbele e = 2; dubbele phi = (p - 1) * (q - 1); while (e /* * e moet co-prime zijn voor phi en * kleiner dan phi. */ if (ggd(e, phi) == 1) break; else e++; } int k = 2; // Een constante waarde double d = (1 + (k * phi)) / e; // Te versleutelen bericht double msg = 12; Console.WriteLine('Berichtgegevens = ' + String.Format('{0:F6} ', msg)); // Codering c = (msg ^ e) % n double c = Math.Pow(msg, e); c = c % n; Format('{0:F6}', c)); // Decryptie m = (c ^ d) % n dubbel m = Math.Pow(c, d); 'Origineel bericht verzonden = ' + String.Format('{0:F6}', m)); } } // Deze code is bijgedragen door Pranay Arora Javascript //GFG //Javascript-code voor deze aanpak function ggd(a, h) { /* * Deze functie retourneert de ggd of grootste gemene deler */ let temp while (true) { temp = a % h if (temp == 0) retourneert h = h; ; h = temp; } } laat p = 3; laat q = 7; // Slaat het eerste deel van de openbare sleutel op: laat n = p * q; // Het andere deel van de publieke sleutel vinden. // e staat voor versleutelen, let e = 2; laat phi = (p - 1) * (q - 1); terwijl (e /* * e co-prime moet zijn met phi en * kleiner dan phi. */ if (ggd(e, phi) == 1) break; else e++; } laat k = 2; // Een constante waarde let d = (1 + (k * phi)) / e; // Te versleutelen bericht let msg = 12; console.log('Berichtgegevens = ' + msg // Codering c = (msg ^ e ) % n let c = Math.pow(msg, e); c = c % n; console.log('Gecodeerde gegevens = ' + c // Decryptie m = (c ^ d) % n let m = Math.pow(c, d); m = m % n; console.log('Origineel bericht verzonden = ' + m); //Deze code is geschreven door Sundaram Uitvoerberichtgegevens = 12.000000 Gecodeerde gegevens = 3.000000 Origineel Bericht verzonden = 12,000000 Methode 2: Tekstberichten met alfabetten en cijfers coderen en decoderen met behulp van hun ASCII-waarde: C++ #include met behulp van naamruimte std; prime; // een set is de verzameling priemgetallen, // waar we willekeurige priemgetallen p en q int public_key kunnen selecteren; int privé_sleutel; int n; // we zullen de functie slechts één keer uitvoeren om de set // priemgetallen te vullen void primefiller() {// methode gebruikt om de set priemgetallen te vullen is seive van // eratosthenes (een methode om priemgetallen te verzamelen) vector seive(250, waar); seive[0] = false; seive[1] = false; voor (int i = 2; ik<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 encoder(tekenreeksbericht) { vector formulier; // de coderingsfunctie aanroepen in de coderingsfunctie voor (auto& letter: message) form.push_back(encrypt((int)letter)); retourformulier; } stringdecoder(vector gecodeerd) { string s; // de decoderingsfunctie aanroepen decoderingsfunctie voor (auto& num: gecodeerd) s += decrypt(num); geeft terug; } int main() { primefiller(); setkeys(); string message = 'Testbericht'; // commentaar hieronder verwijderen voor handmatige invoer // cout<<'enter the message
';getline(cin,message); // calling the encoding function vector gecodeerd = encoder(bericht); uit<< '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) { gecodeerde_tekst *= bericht; gecodeerde_tekst %= n; e-= 1; } retourneer gecodeerde_tekst; } publieke statische int decrypt(int versleutelde_tekst) { int d = private_key; int gedecodeerd = 1; terwijl (d> 0) { gedecodeerd *= gecodeerde_tekst; gedecodeerd %= n; d-= 1; } retour gedecodeerd; } publieke statische int ggd(int a, int b) { if (b == 0) { return a; } return ggd(b, a % b); } openbare statische lijst-encoder (String-bericht) { Lijst gecodeerd = nieuwe ArrayList (); for (char letter: message.toCharArray()) { encoded.add(encrypt((int)letter)); } return gecodeerd; } openbare statische String-decoder (lijst gecodeerd) { StringBuilder s = nieuwe StringBuilder (); for (int num: gecodeerd) { s.append((char)decrypt(num)); } return s.toString(); } } Python3 import willekeurige import wiskunde # Een set zal de verzameling priemgetallen zijn, # waar we willekeurige priemgetallen p en q kunnen selecteren prime = set() public_key = Geen private_key = Geen n = Geen # We zullen de functie slechts één keer uitvoeren om de set van # priemgetallen te vullen def primefiller(): # Methode gebruikt om de set van priemgetallen te vullen is Zeef van # Eratosthenes (een methode om priemgetallen te verzamelen) seive = [True] * 250 seive[0] = False seive[1 ] = Onwaar voor i binnen bereik(2, 250): voor j binnen bereik(i * 2, 250, i): seive[j] = Onwaar # De priemgetallen invullen voor i binnen bereik(len(seive)): if seive[i]: prime.add(i) # Een willekeurig priemgetal kiezen en dat priemgetal # uit de lijst wissen omdat p!=q def pickrandomprime(): globaal priemgetal k = random.randint(0, len(prime) - 1) it = iter(prime) for _ in range(k): next(it) ret = next(it) prime.remove(ret) return ret def setkeys(): global public_key, private_key, n prime1 = pickrandomprime() # Eerste priemgetal prime2 = pickrandomprime() # Tweede priemgetal n = prime1 * prime2 fi = (prime1 - 1) * (prime2 - 1) e = 2 while True: als math.gcd(e, fi) == 1: break e += 1 # d = (k*Φ(n) + 1) / e voor een geheel getal k public_key = e d = 2 while True: if (d * e) % fi == 1: break d += 1 private_key = d # Om het gegeven getal te coderen def encrypt(message): global public_key, n e = public_key Encrypted_text = 1 while e> 0: Encrypted_text *= message Encrypted_text %= n e -= 1 return Encrypted_text # Om het gegeven getal te decrypten Def Decrypt( versleutelde_tekst): globale privé_sleutel, n d = privé_sleutel gedecodeerd = 1 terwijl d> 0: gedecodeerd *= gecodeerde_tekst gedecodeerd %= n d -= 1 return gedecodeerd # Eerst elk teken converteren naar zijn ASCII-waarde en # vervolgens coderen en vervolgens het te verkrijgen getal decoderen de # ASCII en converteer deze naar karakter def encoder(bericht): encoded = [] # Roep de versleutelingsfunctie aan in de coderingsfunctie voor een letter in het bericht: encoded.append(encrypt(ord(letter))) return gecodeerde def decoder(gecodeerd) : s = '' # De decoderingsfunctie aanroepen decoderingsfunctie voor num in gecodeerd: s += chr(decrypt(num)) return s if __name__ == '__main__': primefiller() setkeys() message = 'Testbericht' # Verwijder commentaar hieronder voor handmatige invoer # message = input('Voer het bericht in
') # Roep de coderingsfunctie aan gecodeerd = encoder(bericht) print('Eerste bericht:') print(bericht ) print('
Het gecodeerde bericht (gecodeerd door publieke sleutel)
') print(''.join(str(p) voor p in gecodeerd)) print('
Het gedecodeerde bericht(gedecodeerd met publieke sleutel)
') print(''.join(str(p) voor p in decoder(gecodeerd))) C# met behulp van System; met behulp van System.Collections.Generic; openbare klasse GFG {privé statische HashSet prime = nieuwe HashSet (); privé statische int? openbare_sleutel = nul; privé statische int? privé_sleutel = nul; privé statische int? n = nul; privé statisch Willekeurig willekeurig = nieuw Willekeurig(); openbare statische leegte Main() { PrimeFiller(); SetKeys(); string message = 'Testbericht'; // Verwijder hieronder de commentaar voor handmatige invoer // Console.WriteLine('Voer het bericht in:'); // bericht = Console.ReadLine(); Lijst gecodeerd = Encoder(bericht); Console.WriteLine('Eerste bericht:'); Console.WriteLine(bericht); Console.WriteLine('
Het gecodeerde bericht (gecodeerd met publieke sleutel)
'); Console.WriteLine(string.Join('', gecodeerd)); Console.WriteLine('
Het gedecodeerde bericht (gedecodeerd met publieke sleutel)
'); Console.WriteLine(Decoder(gecodeerd)); } openbare statische leegte PrimeFiller() { bool[] zeef = nieuwe bool[250]; voor (int i = 0; ik<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) { gecodeerde_tekst *= bericht; gecodeerde_tekst %= n.Waarde; e-= 1; } retourneer gecodeerde_tekst; } publieke statische int Decrypt(int versleutelde_tekst) { int d = private_key.Value; int gedecodeerd = 1; terwijl (d> 0) { gedecodeerd *= gecodeerde_tekst; gedecodeerd %= n.Waarde; d-= 1; } retour gedecodeerd; } publieke statische int GCD(int a, int b) { if (b == 0) { return a; } retourneer GCD(b, a % b); } openbare statische lijst Encoder(tekenreeksbericht) {Lijst gecodeerd = nieuwe lijst (); foreach (char-letter in bericht) { gecodeerd.Add(Encrypt((int)letter)); } return gecodeerd; } openbare statische tekenreeksdecoder (List gecodeerd) { string s = ''; foreach (int num in gecodeerd) { s += (char)Decrypt(num); } geeft terug; } } Uitvoer Initiële boodschap: Testbericht Het gecodeerde bericht (gecodeerd door publieke sleutel) 863312887135951593413927434912887135951359583051879012887 Het gedecodeerde bericht (gedecodeerd door private sleutel) Testbericht Implementatie van RSA Cryptosysteem met Primitive Roots in C++ we zullen een eenvoudige versie van RSA implementeren met behulp van prim itieve wortels. Stap 1: Sleutels genereren Om te beginnen moeten we twee grote priemgetallen genereren, p en q. Deze priemgetallen moeten ongeveer even lang zijn en hun product moet veel groter zijn dan het bericht dat we willen coderen. We kunnen de priemgetallen genereren met behulp van elk primaliteitstestalgoritme, zoals de Miller-Rabin-test. Zodra we de twee priemgetallen hebben, kunnen we hun product n = p*q berekenen, wat de modulus voor ons RSA-systeem zal zijn. Vervolgens moeten we een geheel getal e kiezen zodat 1. Om de exponent d van de privésleutel te berekenen, moeten we een geheel getal d vinden zodat d*e = 1 (mod phi(n)). Dit kan worden gedaan met behulp van het uitgebreide Euclidische algoritme. Onze publieke sleutel is (n, e) en onze privésleutel is (n, d). Stap 2: Encryptie Om een bericht m te coderen, moeten we het converteren naar een geheel getal tussen 0 en n-1. Dit kan worden gedaan met behulp van een omkeerbaar coderingsschema, zoals ASCII of UTF-8. Zodra we de gehele representatie van het bericht hebben, berekenen we de cijfertekst c als c = m^e (mod n). Dit kan efficiënt worden gedaan met behulp van modulaire machtsverheffingsalgoritmen, zoals binaire machtsverheffing. Stap 3: Decryptie Om de cijfertekst c te decoderen, berekenen we de leesbare tekst m als m = c^d (mod n). Nogmaals, we kunnen modulaire machtsverheffingsalgoritmen gebruiken om dit efficiënt te doen. Stap 4: Voorbeeld Laten we een voorbeeld doornemen met kleine waarden om te illustreren hoe het RSA-cryptosysteem werkt. Stel dat we p = 11 en q = 13 kiezen, wat ons n = 143 en phi(n) = 120 geeft. We kunnen e = 7 kiezen, aangezien ggd(7, 120) = 1. Met behulp van het uitgebreide Euclidische algoritme kunnen we berekenen d = 103, aangezien 7*103 = 1 (mod. 120). Onze publieke sleutel is (143, 7) en onze privésleutel is (143, 103). Stel dat we het bericht HALLO willen versleutelen. We kunnen dit converteren naar het gehele getal 726564766, met behulp van ASCII-codering. Met behulp van de openbare sleutel berekenen we de cijfertekst als c = 726564766^7 (mod 143) = 32. Om de cijfertekst te decoderen, gebruiken we de privésleutel om m = 32^103 (mod 143) = 726564766 te berekenen, wat de originele sleutel is bericht. Voorbeeldcode: C++ #include #include met naamruimte std; // bereken phi(n) voor een gegeven getal n int phi(int n) { int resultaat = n; voor (int i = 2; ik<= sqrt(n); i++) { if (n % i == 0) { while (n % i == 0) { n /= i; } result -= result / i; } } if (n>1) { resultaat -= resultaat / n; } retourresultaat; } // bereken ggd(a, b) met behulp van het Euclidische algoritme int ggd(int a, int b) { if (b == 0) { return a; } return ggd(b, a % b); } // bereken a^b mod m met behulp van modulaire machtsverheffing int modpow(int a, int b, int m) { int resultaat = 1; terwijl (b> 0) { if (b & 1) { resultaat = (resultaat * a) % m; } een = (een * een) % m; b>>= 1; } retourresultaat; } // genereer een willekeurige primitieve wortel modulo n int genererenPrimitiveRoot(int n) { int phiN = phi(n); int factoren[phiN], numFactors = 0; int temp = phiN; // haal alle priemfactoren van phi(n) op voor (int i = 2; i<= sqrt(temp); i++) { if (temp % i == 0) { factors[numFactors++] = i; while (temp % i == 0) { temp /= i; } } } if (temp>1) { factoren[numFactors++] = temp; } // test mogelijke primitieve wortels voor (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.>