logo

Algoritmus RSA v kryptografii

Algoritmus RSA je asymetrický kryptografický algoritmus. Asymetrický vlastně znamená, že funguje na dvou různých klávesách tzn. Veřejný klíč a Soukromý klíč. Jak název napovídá, veřejný klíč je dán všem a soukromý klíč je soukromý.

násobení matic v c

Příklad asymetrické kryptografie:

  1. Klient (například prohlížeč) odešle svůj veřejný klíč na server a požádá o některá data.
  2. Server zašifruje data pomocí veřejného klíče klienta a odešle zašifrovaná data.
  3. Klient obdrží tato data a dešifruje je.

Protože je to asymetrické, nikdo jiný kromě prohlížeče nemůže dešifrovat data, i když třetí strana má veřejný klíč prohlížeče.



Idea! Myšlenka RSA je založena na skutečnosti, že je obtížné faktorizovat velké celé číslo. Veřejný klíč se skládá ze dvou čísel, kde jedno číslo je násobením dvou velkých prvočísel. A soukromý klíč je také odvozen od stejných dvou prvočísel. Takže pokud někdo může faktorizovat velké číslo, soukromý klíč je kompromitován. Síla šifrování tedy zcela závisí na velikosti klíče a pokud zdvojnásobíme nebo ztrojnásobíme velikost klíče, síla šifrování exponenciálně vzroste. Klíče RSA mohou být obvykle dlouhé 1024 nebo 2048 bitů, ale odborníci se domnívají, že 1024bitové klíče by mohly být v blízké budoucnosti prolomeny. Ale zatím se to zdá jako nesplnitelný úkol.

Pojďme se naučit mechanismus za algoritmem RSA:>> Generování veřejného klíče:

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],    >> Generování soukromého klíče: Musíme vypočítat Φ(n) : Tak, že Φ(n) = (P-1)(Q-1), takže, Φ(n) = 3016 Nyní vypočítejte soukromý klíč, d : d = (k *Φ(n) + 1) / e pro nějaké celé číslo k Pro k = 2 je hodnota d 2011. Nyní jsme připraveni s naším – veřejným klíčem ( n = 3127 a e = 3) a soukromým klíčem (d = 2011 ) Nyní zašifrujeme HI : Převedeme písmena na čísla : H = 8 a I = 9 Takto zašifrovaná data c = (89 e )mod n Naše šifrovaná data tedy vyjdou na 1394 Nyní dešifrujeme 1394 : Dešifrovaná data = (c d )mod n Naše šifrovaná data tedy vycházejí jako 89 8 = H a I = 9, tj. 'HI'.    Níže je uvedena implementace algoritmu RSA pro metodu 1: Šifrování a dešifrování malých číselných hodnot: C++ // Program C pro asymetrický kryptografický // algoritmus RSA. Pro demonstraci jsou hodnoty // relativně malé ve srovnání s praktickou // aplikací #include using namespace std; // Vrátí gcd z a a b int gcd(int a, int h) { int temp;  zatímco (1) { teplota = a % h;  if (temp == 0) return h;  a = h;  h = teplota;  } } // Kód pro demonstraci algoritmu RSA int main() { // Dvě náhodná prvočísla double p = 3;  dvojité q = 7;  // První část veřejného klíče: double n = p * q;  // Nalezení jiné části veřejného klíče.  // e znamená encrypt double e = 2;  dvojité fí = (p - 1) * (q - 1);  while (e // e musí být co-prime k phi a // menší než phi. if (gcd(e, phi) == 1) break; else e++; } // Soukromý klíč (d znamená dešifrovat) // zvolení d takové, že vyhovuje // d*e = 1 + k * totient int k = 2 // Konstantní hodnota double d = (1 + (k * phi)) / e Zpráva k zašifrování double msg = 12 printf('Data zprávy = %lf', msg) // Šifrování c = (msg ^ e) % n double c = pow(msg, e); ('
Zašifrovaná data = %lf', c // Dešifrování m = (c ^ d) % n double m = pow(c, d = fmod(m, n); 
Původní zpráva odeslána = %lf', m return 0 } // Tento kód přidal Akash Sharan /*balíček cokoliv //nepište sem název balíčku */ import java.io.*; java.math.*; import java.util.*; /* * Java program pro asymetrický kryptografický algoritmus RSA * Pro ukázku, hodnoty jsou * relativně malé ve srovnání s praktickou aplikací */ public class GFG { public static double gcd(double a. , double h) { /* * Tato funkce vrací gcd nebo největší společný * dělitel */ double temp;  while (true) { temp = a % h;  if (temp == 0) return h;  a = h;  h = teplota;  } } public static void main(String[] args) { double p = 3;  dvojité q = 7;  // Uloží první část veřejného klíče: double n = p * q;  // Nalezení druhé části veřejného klíče.  // double e znamená zašifrovat double e = 2;  dvojité fí = (p - 1) * (q - 1);  while (e /* * e musí být prvočíslo k phi a * menší než phi. */ if (gcd(e, phi) == 1) break; jinak e++; } int k = 2; // Konstantní hodnota double d = (1 + (k * phi)) / e; // Zpráva k zašifrování double msg = 12; ^ e) % n double c = Math.pow(msg, e); c = c % n System.out.println('Zašifrovaná data = ' + c // Dešifrování m = (c ^ d) % n double m = Math.pow(c, d); m = m % n; System.out.println('Původní zpráva odeslána = ' + m); Python3 # Python pro asymetrický kryptografický algoritmus RSA # Pro demonstraci jsou hodnoty # relativně malé ve srovnání s matematickým importem praktické aplikace def gcd(a, h): temp = 0 while(1): temp = a % h if (temp ==. 0): návrat h a = h h = teplota p = 3 q = 7 n = p*q e = 2 phi = (p-1)*(q-1), zatímco (e # e musí být prvočíslo k phi a # menší než phi (gcd(e, phi) == 1): break else: e = e+1 # Soukromý klíč (d znamená dešifrovat) # výběr d tak, aby vyhovoval # d*e = 1 + k * totient. k = 2 d = (1 + (k*phi))/e # Zpráva k zašifrování msg = 12.0 print('Data zprávy = ', msg) # Šifrování c = (zpráva ^ e) % n c = pow( msg, e) c = math.fmod(c, n) print('Zašifrovaná data = ', c) # Dešifrování m = (c ^ d) % n m = pow(c, d) m = math.fmod( m, n) print('Original Message Sent = ', m) # Tento kód přispěl Pranay Arora.  C# /* * C# program pro asymetrický kryptografický algoritmus RSA.  * Pro demonstraci jsou hodnoty * relativně malé ve srovnání s praktickou aplikací */ pomocí System; public class GFG { public static double gcd(double a, double h) { /* * Tato funkce vrací gcd nebo největší společný * dělitel */ double temp;  while (true) { temp = a % h;  if (temp == 0) return h;  a = h;  h = teplota;  } } static void Main() { double p = 3;  dvojité q = 7;  // Uloží první část veřejného klíče: double n = p * q;  // Nalezení druhé části veřejného klíče.  // double e znamená zašifrovat double e = 2;  dvojité phi = (p - 1) * (q - 1);  while (e /* * e musí být prvočíslo k phi a * menší než phi. */ if (gcd(e, phi) == 1) break; jinak e++; } int k = 2; // Konstantní hodnota double d = (1 + (k * phi)) / e // Zpráva k zašifrování double msg = 12; Console.WriteLine('Data zprávy = ' + String.Format('{0:F6} ', msg)); // Šifrování c = (msg ^ e) % n double c = Math.Pow(msg, e Console.WriteLine('Zašifrovaná data = ' + String); Format('{0:F6}', c)); // Dešifrování m = (c ^ d) % n double m = Math.Pow(c, d) = m % n; 'Původní zpráva odeslána = ' + String.Format('{0:F6}', m)); function gcd(a, h) { /* * Tato funkce vrací gcd nebo největší společný * dělitel */ let temp while (true) { temp = a % h if (temp == 0) return h; ; h = temp } let p = 3; // Uloží první část veřejného klíče: let n = p * q; // Nalezení druhé části veřejného klíče. // e znamená zašifrovat let e = 2; nech phi = (p - 1) * (q - 1); while (e /* * e musí být prvočíslo k phi a * menší než phi. */ if (gcd(e, phi) == 1) break; jinak e++; } nechť k = 2; // Konstantní hodnota let d = (1 + (k * phi)) / e; // Zpráva, která má být zašifrována let msg = 12; ) % n let c = Math.pow(msg, e); c = c % n; console.log('Zašifrovaná data = ' + c // Dešifrování m = (c ^ d) % n let m); = Math.pow(c, d); m = m % n console.log('Původní zpráva odeslána = ' + m); Zpráva odeslána = 12,000000 Metoda 2: Šifrování a dešifrování zpráv ve formátu prostého textu obsahujících abecedy a čísla pomocí jejich hodnoty ASCII: C++ #include using namespace std set; primární; // množina bude sbírka prvočísel, // kde můžeme vybrat náhodná prvočísla p a q int veřejný_klíč; int privátní_klíč; int n; // funkci spustíme pouze jednou, abychom naplnili množinu // prvočísel void primefiller() { // metoda použitá k vyplnění množiny prvočísel je seive of // eratosthenes (metoda pro sběr prvočísel) vektor seive(250, pravda);  seive[0] = nepravda;  seive[1] = nepravda;  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ér(řetězcová zpráva) { vektor formulář;  // volání šifrovací funkce ve funkci kódování pro (auto& písmeno : zpráva) form.push_back(encrypt((int)letter));  formulář pro vrácení; } řetězcový dekodér(vektor zakódováno) { řetězec s;  // volání dešifrovací funkce dekódovací funkce pro (auto& num : zakódováno) s += decrypt(num);  návrat s; } int main() { primefiller();  setkeys();  string message = 'Testovací zpráva';  // odkomentujte níže pro ruční zadání // cout<<'enter the message
';getline(cin,message);  // calling the encoding function  vector kódováno = kodér(zpráva);  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) { zašifrovaný_text *= zpráva;  zašifrovaný_text %= n;  e= 1;  } return encrypted_text;  } public static int decrypt(int encrypted_text) { int d = private_key;  int dešifrováno = 1;  while (d> 0) { dešifrováno *= zašifrovaný_text;  dešifrováno %= n;  d = 1;  } return dešifrováno;  } public static int gcd(int a, int b) { if (b == 0) { return a;  } return gcd(b, a % b);  } public static List kodér(String message) { List encoded = new ArrayList();  for (písmeno znaku: message.toCharArray()) { encoded.add(encrypt((int)letter));  } return zakódováno;  } public static String decoder(List encoded) { StringBuilder s = new StringBuilder();  for (int num : zakódováno) { s.append((char)decrypt(num));  } return s.toString();  } } Python3 import náhodný import matematika # Množina bude sbírka prvočísel, # kde můžeme vybrat náhodná prvočísla p a q prime = set() public_key = Žádný private_key = Žádný n = Žádný # Funkci spustíme pouze jednou k vyplnění sady # prvočísel def primefiller(): # Metoda použitá k vyplnění sady prvočísel je Sieve of # Eratosthenes (metoda pro sběr prvočísel) seive = [True] * 250 seive[0] = False seive[1 ] = False pro i v rozsahu(2, 250): pro j v rozsahu(i * 2, 250, i): seive[j] = False # Vyplnění prvočísel pro i v rozsahu(len(seive)): pokud seive[i]: prime.add(i) # Výběr náhodného prvočísla a vymazání tohoto prvočísla ze seznamu, protože p!=q def pickrandomprime(): globální prvočíslo 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() # První prvočíslo prime2 = pickrandomprime() # Druhé prvočíslo n = prvočíslo1 * prvočíslo2 fi = (prvočíslo1 - 1) * (prvočíslo2 - 1) e = 2, zatímco True: if math.gcd(e, fi) == 1: zlom e += 1 # d = (k*Φ(n) + 1) / e pro nějaké celé číslo k veřejný_klíč = e d = 2, zatímco True: if (d * e) % fi == 1: zlom d += 1 soukromý_klíč = d # Zašifrovat dané číslo def encrypt(zpráva): global public_key, n e = public_key encrypted_text = 1 while e> 0: encrypted_text *= message encrypted_text %= n e -= 1 return encrypted_text # Pro dešifrování daného čísla def decrypt( encrypted_text): global private_key, n d = private_key decrypted = 1 while d> 0: decrypted *= encrypted_text decrypted %= n d -= 1 return decrypted # Nejprve převeďte každý znak na jeho hodnotu ASCII a # poté jej zakódujte a poté dekódujte číslo, abyste získali # ASCII a jeho převedení na znak def kodér(zpráva): encoded = [] # Volání šifrovací funkce ve funkci kódování pro písmeno ve zprávě: encoded.append(encrypt(ord(písmeno))) return zakódované def decoder(encoded) : s = '' # Volání dešifrovací funkce dekódovací funkce pro num in kódováno: s += chr(decrypt(num)) return s if __name__ == '__main__': primefiller() setkeys() message =  'Testovací zpráva' # Odkomentujte níže pro ruční zadání # zpráva = input('Zadejte zprávu
') # Volání funkce kódování coded = kodér(zpráva) tisk('Počáteční zpráva:') tisk(zpráva ) print('

Zakódovaná zpráva (šifrovaná veřejným klíčem)
') print(''.join(str(p) pro p v kódovaném)) print('

Dekódovaná zpráva(dešifrováno veřejným klíčem)
') print(''.join(str(p) pro p v dekodéru(kódováno))) C# pomocí System; pomocí System.Collections.Generic; public class GFG { private static HashSet prime = nový HashSet ();  soukromý statický int? public_key = null;  soukromý statický int? private_key = null;  soukromý statický int? n = null;  private static Random random = new Random();  public static void Main() { PrimeFiller();  SetKeys();  string message = 'Testovací zpráva';  // Odkomentujte níže pro ruční zadání // Console.WriteLine('Zadejte zprávu:');  // zpráva = Console.ReadLine();  Seznam kódováno = Kodér(zpráva);  Console.WriteLine('Počáteční zpráva:');  Console.WriteLine(zpráva);  Console.WriteLine('

Zakódovaná zpráva (zašifrovaná veřejným klíčem)
');  Console.WriteLine(string.Join('', kódováno));  Console.WriteLine('

Dekódovaná zpráva (dešifrovaná veřejným klíčem)
');  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) { zašifrovaný_text *= zpráva;  encrypted_text %= n.Value;  e= 1;  } return encrypted_text;  } public static int Dešifrovat(int zašifrovaný_text) { int d = soukromý_klíč.Hodnota;  int dešifrováno = 1;  while (d> 0) { dešifrováno *= zašifrovaný_text;  dešifrováno %= n.Value;  d = 1;  } return dešifrováno;  } public static int GCD(int a, int b) { if (b == 0) { return a;  } return GCD(b, a % b);  } veřejný statický seznam Kodér (řetězcová zpráva) { Seznam zakódováno = nový seznam ();  foreach (písmeno char ve zprávě) { zakódováno.Add(Zašifrovat((int)písmeno));  } return zakódováno;  } public static string Decoder(List zakódováno) { řetězec s = '';  foreach (int num in zakódováno) { s += (char)Decrypt(num);  } return s;  } } Výstup Počáteční zpráva: Test Message Zakódovaná zpráva (šifrovaná veřejným klíčem) 863312887135951593413927434912887135951359583051879012887 Dekódovaná zpráva (dešifrovaná pomocí soukromého klíče RImpot implementuje jednoduchou verzi RSA pomocí primitivních kořenů.   Krok 1: Generování klíčů Pro začátek potřebujeme vygenerovat dvě velká prvočísla, p a q. Tato prvočísla by měla mít zhruba stejnou délku a jejich součin by měl být mnohem větší než zpráva, kterou chceme zašifrovat. Prvočísla můžeme generovat pomocí libovolného algoritmu testování primality, jako je Miller-Rabinův test. Jakmile máme dvě prvočísla, můžeme vypočítat jejich součin n = p*q, což bude modul pro náš systém RSA. Dále musíme zvolit celé číslo e takové, že 1 Abychom vypočítali exponent soukromého klíče d, musíme najít celé číslo d takové, že d*e = 1 (mod phi(n)). To lze provést pomocí rozšířeného euklidovského algoritmu. Náš veřejný klíč je (n, e) a náš soukromý klíč je (n, d).   Krok 2: Šifrování Abychom zašifrovali zprávu m, musíme ji převést na celé číslo mezi 0 a n-1. To lze provést pomocí schématu reverzibilního kódování, jako je ASCII nebo UTF-8. Jakmile máme celočíselnou reprezentaci zprávy, vypočítáme šifrový text c jako c = m^e (mod n). To lze efektivně provést pomocí modulárních umocňovacích algoritmů, jako je binární umocňování.   Krok 3: Dešifrování Abychom dešifrovali šifrový text c, vypočítáme prostý text m jako m = c^d (mod n). Opět můžeme použít modulární umocňovací algoritmy, abychom toho dosáhli efektivně.   Krok 4: Příklad Projděme si příklad s použitím malých hodnot, abychom ilustrovali, jak funguje kryptosystém RSA. Předpokládejme, že zvolíme p = 11 a q = 13, což nám dává n = 143 a phi(n) = 120. Můžeme zvolit e = 7, protože gcd(7, 120) = 1. Pomocí rozšířeného euklidovského algoritmu můžeme vypočítat d = 103, protože 7*103 = 1 (mod 120). Náš veřejný klíč je (143, 7) a náš soukromý klíč je (143, 103). Předpokládejme, že chceme zašifrovat zprávu HELLO. Můžeme to převést na celé číslo 726564766 pomocí kódování ASCII. Pomocí veřejného klíče vypočítáme šifrový text jako c = 726564766^7 (mod 143) = 32. K dešifrování šifrovaného textu použijeme soukromý klíč k výpočtu m = 32^103 (mod 143) = 726564766, což je původní zpráva. Příklad kódu: C++ #include #include using namespace std; // výpočet phi(n) pro dané číslo n int phi(int n) { int vysledek = 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) { vysledek -= vysledek / n;  } vrátit výsledek; } // výpočet gcd(a, b) pomocí euklidovského algoritmu int gcd(int a, int b) { if (b == 0) { return a;  } return gcd(b, a % b); } // výpočet a^b mod m pomocí modulárního umocňování int modpow(int a, int b, int m) { int vysledek = 1;  while (b> 0) { if (b & 1) { vysledek = (vysledek * a) % m;  } a = (a * a) % m;  b>>= 1;  } vrátit výsledek; } // vygenerování náhodného primitivního kořene modulo n int vygenerováníPrimitiveRoot(int n) { int phiN = phi(n);  int faktory[phiN], numFactors = 0;  int temp = phiN;  // získáme všechny prvočinitele phi(n) pro (int i = 2; i<= sqrt(temp); i++) {  if (temp % i == 0) {  factors[numFactors++] = i;  while (temp % i == 0) {  temp /= i;  }  }  }  if (temp>1) { faktory[numFactors++] = temp;  } // otestujte možné primitivní kořeny pro (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.  >