RSA-algoritmi on epäsymmetrinen salausalgoritmi. Epäsymmetrinen tarkoittaa itse asiassa, että se toimii kahdella eri näppäimellä, ts. Julkinen avain ja Yksityinen avain. Kuten nimi kertoo, että julkinen avain annetaan kaikille ja yksityinen avain pidetään yksityisenä.
tiikerin ja leijonan ero
Esimerkki epäsymmetrisestä salakirjoituksesta:
- Asiakas (esimerkiksi selain) lähettää julkisen avaimensa palvelimelle ja pyytää tietoja.
- Palvelin salaa tiedot asiakkaan julkisella avaimella ja lähettää salatut tiedot.
- Asiakas vastaanottaa nämä tiedot ja purkaa sen salauksen.
Koska tämä on epäsymmetrinen, kukaan muu paitsi selain ei voi purkaa tietojen salausta, vaikka kolmannella osapuolella olisi selaimen julkinen avain.
Ajatus! RSA:n idea perustuu siihen, että suurta kokonaislukua on vaikea kertoa. Julkinen avain koostuu kahdesta luvusta, joista yksi luku on kahden suuren alkuluvun kertolasku. Ja yksityinen avain on myös johdettu samoista kahdesta alkuluvusta. Joten jos joku voi jakaa suuren luvun, yksityinen avain vaarantuu. Siksi salauksen vahvuus riippuu täysin avaimen koosta ja jos avaimen koko kaksin- tai kolminkertaistuu, salauksen vahvuus kasvaa eksponentiaalisesti. RSA-avaimet voivat olla tyypillisesti 1024 tai 2048 bitin pituisia, mutta asiantuntijat uskovat, että 1024-bittiset avaimet voivat rikkoutua lähitulevaisuudessa. Mutta toistaiseksi se näyttää olevan mahdoton tehtävä.
Opitaanpa RSA-algoritmin takana oleva mekanismi:>> Julkisen avaimen luominen:
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],>> Yksityisen avaimen luominen: Meidän on laskettava Φ(n) : siten, että Φ(n) = (P-1)(Q-1) joten Φ(n) = 3016 Laske nyt yksityinen avain, d : d = (k *Φ(n) + 1) / e jollekin kokonaisluvulle k Jos k = 2, d:n arvo on 2011. Nyt olemme valmiita käyttämään julkista avainta (n = 3127 ja e = 3) ja yksityistä avainta (d = 2011). ) Nyt salataan HI : Muunna kirjaimet numeroiksi : H = 8 ja I = 9 Näin salatut tiedot c = (89 e )mod n Näin salatut tiedot tulevat olemaan 1394 Nyt puretaan salaus 1394 : Purettu data = (c d )mod n Näin ollen salatut tiedot ovat 89 8 = H ja I = 9 eli 'HI'. Alla on RSA-algoritmin toteutus tapaa 1 varten: Pienten numeroarvojen salaus ja salauksen purku: C++ // C-ohjelma RSA:n epäsymmetriselle salausalgoritmille //. Esittelyssä arvot ovat // suhteellisen pieniä verrattuna käytännön // sovellukseen #include using namespace std; // Palauttaa a:n ja b:n gcd:n int gcd(int a, int h) { int temp; while (1) { lämpötila = a % h; if (temp == 0) paluu h; a = h; h = lämpötila; } } // RSA-algoritmin esittelykoodi int main() { // Kaksi satunnaista alkulukua double p = 3; kaksoisq = 7; // Julkisen avaimen ensimmäinen osa: double n = p * q; // Julkisen avaimen muun osan löytäminen. // e on encrypt double e = 2; kaksinkertainen phi = (p - 1) * (q - 1); while (e // e:n on oltava co-prime phi:lle ja // pienempi kuin phi. if (gcd(e, phi) == 1) break; else e++; } // Yksityinen avain (d tarkoittaa salauksen purkamista) // valitsemalla d niin, että se täyttää // d*e = 1 + k * totient k = 2 // Vakioarvo double d = (1 + (k * phi)) // Salattava viesti kaksoisviesti; = 12 printf('Viesti data = %lf', msg) % n double c = pow(msg, n); ('
Salatut tiedot = %lf', c // Salauksen purku m = (c ^ d) % n double m = pow(c, d) m = fmod(m, n);
Alkuperäinen viesti lähetetty = %lf', m); java.math.*; tuonti java.util.*; , double h) { /* * Tämä funktio palauttaa gcd:n tai suurimman yhteisen * jakajan */ double temp; while (tosi) { temp = a % h; if (temp == 0) paluu h; a = h; h = lämpötila; } } julkinen staattinen void main(String[] args) { double p = 3; kaksoisq = 7; // Tallentaa julkisen avaimen ensimmäisen osan: double n = p * q; // Julkisen avaimen toisen osan löytäminen. // double e tarkoittaa salaa double e = 2; kaksinkertainen phi = (p - 1) * (q - 1); while (e /* * e:n on oltava phi:n yhteisalkuluku ja * pienempi kuin phi. */ if (gcd(e, phi) == 1) break; else e++; } int k = 2; // Vakioarvo double d = (1 + (k * phi)) / e salattava viesti double msg = 12 System.out.println('Message data = ' + msg; ^ e) % n double c = Math.pow(msg, e = c % n;'Salatut tiedot = ' + c); % n double m = Math.pow(c, d) m = m % n; Python3 # Python RSA:n epäsymmetriselle salausalgoritmille # Esittelyä varten arvot ovat # suhteellisen pieniä verrattuna käytännön sovelluksiin, math def gcd(a, h): temp = 0 while(1): temp = a % h if (temp ==. 0): paluu h a = h h = lämpötila p = 3 q = 7 n = p*q e = 2 phi = (p-1)*(q-1) kun taas (e # e on oltava phi:n yhteisalkuluku ja # pienempi kuin phi if(gcd(e, phi) == 1): break else: e = e+1 # Yksityinen avain (d tarkoittaa salauksen purkamista) # valitsemalla d siten, että se täyttää # d*e = 1 + k * totient. k = 2 d = (1 + (k*phi))/e # Salattava viesti msg = 12.0 print('Message data = ', msg) # Salaus c = (msg ^ e) % n c = pow( msg, e) c = math.fmod(c, n) print('Salatut tiedot = ', c) # Salauksen purku m = (c ^ d) % n m = pow(c, d) m = math.fmod( m, n) print('Original Message Sent = ', m) # Tämän koodin on lähettänyt Pranay Arora. C# /* * C#-ohjelma RSA:n epäsymmetriselle salausalgoritmille. * Esittelyä varten arvot ovat * suhteellisen pieniä verrattuna käytännön sovelluksiin */ System; public class GFG { public static double gcd(double a, double h) { /* * Tämä funktio palauttaa gcd:n tai suurimman yhteisen * jakajan */ double temp; while (tosi) { temp = a % h; if (temp == 0) paluu h; a = h; h = lämpötila; } } staattinen void Main() { double p = 3; kaksoisq = 7; // Tallentaa julkisen avaimen ensimmäisen osan: double n = p * q; // Julkisen avaimen toisen osan löytäminen. // double e tarkoittaa salaa double e = 2; kaksinkertainen phi = (p - 1) * (q - 1); while (e /* * e:n on oltava phi:n yhteisalkuluku ja * pienempi kuin phi. */ if (gcd(e, phi) == 1) break; else e++; } int k = 2; // Vakioarvo double d = (1 + (k * phi)) / e // Salattava viesti double msg = 12 ('Message data = ' + String.Format('{0:F6}; ', msg)); // Salaus c = (msg ^ e) % n double c = Math.Pow(msg, e = c % n; Muoto('{0:F6}', c)); // Salauksen purku m = (c ^ d) % n double m = Math.Pow(c, d) m = m % n 'Alkuperäinen viesti lähetetty = ' + String.Format('{0:F6}', m)); function gcd(a, h) { /* * Tämä funktio palauttaa gcd:n tai suurimman yhteisen */ anna temp while (true) { temp = a % h; h = temp } anna p = 7 // Tallentaa julkisen avaimen ensimmäisen osan: anna n = p * q; // Julkisen avaimen toisen osan löytäminen. // e tarkoittaa salaa let e = 2; olkoon phi = (p - 1) * (q - 1); while (e /* * e:n on oltava phi:n yhteisalkuluku ja * pienempi kuin phi. */ if (gcd(e, phi) == 1) tauko; else e++; } olkoon k = 2; // Vakioarvo anna d = (1 + (k * phi)) / e // Salattava viesti anna msg = 12 console.log('Message data = ' + msg; ) % n anna c = Math.pow(msg, e) = c % n; = Math.pow(c, d) = m % n; Viesti lähetetty = 12,000000 Tapa 2: Aakkoset ja numerot sisältävien tekstiviestien salaus ja salauksen purku käyttämällä ASCII-arvoa: C++ #include käyttämällä nimiavaruutta std prime; // joukko tulee olemaan alkulukujen kokoelma, // jossa voimme valita satunnaiset alkuluvut p ja q int public_key; int yksityinen_avain; int n; // suoritamme funktion vain kerran täyttääksemme alkulukujoukon // void primefiller() { // alkulukujoukon täyttämiseen käytetty menetelmä on seive of // eratosthenes(menetelmä alkulukujen keräämiseen) vektorista seive(250, tosi); seive[0] = epätosi; seive[1] = epätosi; 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 kooderi(merkkijonoviesti) { vektori muoto; // salausfunktion kutsuminen koodausfunktiossa for (auto& kirjain : viesti) form.push_back(encrypt((int)letter)); palautuslomake; } merkkijono dekooderi(vektori koodattu) { merkkijono s; // salauksenpurkufunktion kutsuminen dekoodausfunktiolle (auto& num : koodattu) s += decrypt(num); paluu s; } int main() { alkutäyte(); setkeys(); string message = 'Testiviesti'; // poista kommentit alta käsinsyöttöä varten // cout<<'enter the message
';getline(cin,message); // calling the encoding function vector koodattu = enkooderi(viesti); 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) { salattu_teksti *= viesti; salattu_teksti %= n; e - = 1; } palauttaa salatun_tekstin; } julkinen staattinen int decrypt(int salattu_teksti) { int d = yksityinen_avain; int purettu = 1; while (d> 0) { salaus purettu *= salattu_teksti; purettu %=n; d = 1; } palauttaa salaus purettu; } public static int gcd(int a, int b) { if (b == 0) { return a; } return gcd(b, a % b); } public static List encoder(String message) { Lista koodattu = new ArrayList(); for (char letter : message.toCharArray()) { koodattu.add(salaa((int)kirjain)); } paluu koodattu; } julkinen staattinen merkkijonon dekooderi(Listakoodattu) { StringBuilder s = new StringBuilder(); for (int num : koodattu) { s.append((char)decrypt(num)); } return s.toString(); } } Python3 tuonti satunnaisen tuonnin matematiikka # Joukko on alkulukujen kokoelma, # jossa voimme valita satunnaiset alkuluvut p ja q alkuluku = set() public_key = Ei mitään private_key = Ei mitään n = Ei mitään # Suoritamme funktion vain kerran täyttääksesi # alkulukujoukon def primefiller(): # Alkulukujoukon täyttämiseen käytetty menetelmä on Sieve of # Eratosthenes (menetelmä alkulukujen keräämiseen) seive = [True] * 250 seive[0] = Väärä seive[1 ] = Epätosi i:lle alueella(2, 250): j:lle alueella(i * 2, 250, i): seive[j] = Väärin # Alkulukujen täyttäminen i:lle alueella(len(seive)): jos seive[i]: prime.add(i) # Satunnaisen alkuluvun valitseminen ja sen alkuluku # poistaminen luettelosta, koska p!=q def pickrandomprime(): globaali alkuluku 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(): globaali julkinen_avain, yksityinen_avain, n alkuluku1 = pickrandomprime() # Ensimmäinen alkuluku alkuluku2 = pickrandomprime() # Toinen alkuluku n = alkuluku1 * alkuluku2 fi = (alkuluku1 - 1) * (alkuluku2 - 1) e = 2, kun taas tosi: jos math.gcd(e, fi) == 1: tauko e += 1 # d = (k*Φ(n) + 1) / e jollekin kokonaisluvulle k julkinen_avain = e d = 2, kun taas True: if (d * e) % fi == 1: break d += 1 yksityinen_avain = d # Tietyn luvun salaamiseen def encrypt(message): globaali julkinen_avain, n e = julkinen_avain salattu_teksti = 1, kun taas e> 0: salattu_teksti *= viesti salattu_teksti %= n e -= 1 return encrypted_text # Annetun numeron salauksen purkaminen def decrypt( salattu_teksti): globaali yksityinen_avain, n d = yksityinen_avain purettu = 1, kun taas d> 0: salaus purettu *= salattu_teksti purettu %= n d -= 1 palauttaa salaus purettu # Muunna ensin jokainen merkki ASCII-arvoonsa ja # sitten koodaus ja sitten dekoodaa numero saadaksesi # ASCII ja sen muuntaminen merkkien def encoderiksi (sanoma): encoded = [] # Salaustoiminnon kutsuminen koodaustoiminnossa viestin kirjaimelle: encoded.append(encrypt(ord(kirjain))) return encoded def decoder(encoded) : s = '' # Salauksen purkufunktion kutsuminen dekoodausfunktiolle num in koodattu: s += chr(decrypt(num)) return s if __name__ == '__main__': primefiller() setkeys() message = 'Testiviesti' # Poista kommentit alta manuaaliselle syötölle # viesti = input('Syötä viesti
') # Koodausfunktion kutsuminen coded = encoder(message) print('Alkuviesti:') print(message ) print('
Koodattu viesti (salattu julkisella avaimella)
') print(''.join(str(p) for p in koodattu)) print('
Dekoodattu viesti(salauksen purettu julkisella avaimella)
') print(''.join(str(p) for p dekooderissa(koodattu))) C# käyttäen System; käyttäen System.Collections.Generic; public class GFG { yksityinen staattinen HashSet alkuluku = uusi HashSet (); yksityinen staattinen int? julkinen_avain = null; yksityinen staattinen int? yksityinen_avain = tyhjä; yksityinen staattinen int? n = nolla; yksityinen staattinen Satunnainen satunnainen = new Satunnainen(); public static void Main() { PrimeFiller(); SetKeys(); string message = 'Testiviesti'; // Poista kommentit alta manuaalista syöttämistä varten // Console.WriteLine('Syötä viesti:'); // viesti = Console.ReadLine(); Lista koodattu = Enkooderi(viesti); Console.WriteLine('Alkuperäinen viesti:'); Console.WriteLine(viesti); Console.WriteLine('
Koodattu viesti (salattu julkisella avaimella)
'); Console.WriteLine(string.Join('', koodattu)); Console.WriteLine('
Dekoodattu viesti (purettu julkisella avaimella)
'); Console.WriteLine(Dekooderi(koodattu)); } public static void PrimeFiller() { bool[] seula = 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) { salattu_teksti *= viesti; salattu_teksti %= n.Arvo; e - = 1; } palauttaa salatun_tekstin; } julkinen staattinen int Pura salaus(int salattu_teksti) { int d = yksityinen_avain.Arvo; int purettu = 1; while (d> 0) { salaus purettu *= salattu_teksti; purettu %= n.Arvo; d = 1; } palauttaa salaus purettu; } julkinen staattinen int GCD(int a, int b) { if (b == 0) { return a; } return GCD(b, a % b); } julkinen staattinen lista Enkooderi(merkkijonoviesti) { List koodattu = uusi lista (); foreach (merkin kirjain viestissä) { koodattu.Lisää(Salaa((int)kirjain)); } paluu koodattu; } julkinen staattinen merkkijono Dekooderi(Lista koodattu) { merkkijono s = ''; foreach (int num in koodattu) { s += (char)Decrypt(num); } return s; } } Lähtö Alkuviesti: Testiviesti Koodattu viesti (salattu julkisella avaimella) 863312887135951593413927434912887135951359583051879012887. Dekoodattu viesti (salauksen purku RSA:n yksityisellä avaimella). toteutamme yksinkertaisen version RSA:sta primitiivisiä juuria käyttäen. Vaihe 1: Avainten luominen Aloittaaksesi meidän on luotava kaksi suurta alkulukua, p ja q. Näiden alkulukujen tulee olla suunnilleen yhtä pitkiä ja niiden tulon tulee olla paljon suurempi kuin salattava viesti. Voimme generoida alkuluvut käyttämällä mitä tahansa primaliteettitestausalgoritmia, kuten Miller-Rabin-testiä. Kun meillä on kaksi alkulukua, voimme laskea niiden tulon n = p*q, joka on RSA-järjestelmämme moduuli. Seuraavaksi meidän on valittava kokonaisluku e siten, että 1 Laskeaksemme yksityisen avaimen eksponentin d, meidän on löydettävä kokonaisluku d siten, että d*e = 1 (mod phi(n)). Tämä voidaan tehdä käyttämällä laajennettua euklidista algoritmia. Julkinen avaimemme on (n, e) ja yksityinen avaimemme (n, d). Vaihe 2: Salaus Salataksemme viestin m, meidän on muutettava se kokonaisluvuksi välillä 0 ja n-1. Tämä voidaan tehdä käyttämällä palautuvaa koodausjärjestelmää, kuten ASCII tai UTF-8. Kun meillä on viestin kokonaislukuesitys, laskemme salatekstin c muodossa c = m^e (mod n). Tämä voidaan tehdä tehokkaasti käyttämällä modulaarisia eksponentioalgoritmeja, kuten binääristä eksponentiota. Vaihe 3: Salauksen purku Salatekstin c salauksen purkamiseksi laskemme selkeän tekstin m muodossa m = c^d (mod n). Jälleen voimme käyttää modulaarisia eksponentioalgoritmeja tehdäksemme tämän tehokkaasti. Vaihe 4: Esimerkki Käydään läpi esimerkki, jossa käytetään pieniä arvoja havainnollistamaan, kuinka RSA-salausjärjestelmä toimii. Oletetaan, että valitsemme p = 11 ja q = 13, jolloin saamme n = 143 ja phi(n) = 120. Voimme valita e = 7, koska gcd(7, 120) = 1. Laajennetun euklidisen algoritmin avulla voimme laskea d = 103, koska 7*103 = 1 (mod 120). Julkinen avaimemme on (143, 7) ja yksityinen avaimemme on (143, 103). Oletetaan, että haluamme salata viestin HELLO. Voimme muuntaa tämän kokonaisluvuksi 726564766 käyttämällä ASCII-koodausta. Laskemme salatekstin julkisella avaimella seuraavasti: c = 726564766^7 (mod 143) = 32. Salatekstin salauksen purkamiseksi käytämme yksityistä avainta laskemaan m = 32^103 (mod 143) = 726564766, joka on alkuperäinen viesti. Esimerkkikoodi: C++ #include #include käyttäen nimiavaruutta std; // laskea phi(n) tietylle luvulle n int phi(int n) { int tulos = 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) { tulos -= tulos / n; } palauttaa tuloksen; } // laske gcd(a, b) euklidisella algoritmilla int gcd(int a, int b) { if (b == 0) { return a; } return gcd(b, a % b); } // laske a^b mod m käyttämällä modulaarista eksponentiota int modpow(int a, int b, int m) { int tulos = 1; while (b> 0) { if (b & 1) { tulos = (tulos * a) % m; } a = (a * a) % m; b>>= 1; } palauttaa tuloksen; } // generoi satunnainen primitiivijuuri modulo n int generoPrimitiveRoot(int n) { int phiN = phi(n); int tekijät[phiN], numFactors = 0; int temp = phN; // saa kaikki phi(n):n alkutekijät arvolle (int i = 2; i<= sqrt(temp); i++) { if (temp % i == 0) { factors[numFactors++] = i; while (temp % i == 0) { temp /= i; } } } if (temp>1) { tekijät[lukutekijät++] = lämpötila; } // testaa mahdollisia primitiivisiä juuria kohteelle (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.>