Advertisement
WHO_IS_THIS_PSH_PSH

hack rsa

May 2nd, 2024 (edited)
718
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.22 KB | None | 0 0
  1. #include <iostream>
  2. #include <cmath>
  3. #include <string>
  4. using namespace std;
  5.  
  6.  
  7. /*
  8. *
  9. Алгоритм отражает процесс генерации открытого и закрытого ключей для шифрования RSA, процесс шифрования и дешифрования сообщения с использованием этих ключей,
  10. а также демонстрирует уязвимость данного алгоритма к взлому(в случае использования маленьких чисел) методом факторизации
  11. *
  12. Факторизация – процесс разложения числа на простые множители.
  13. НОД – наибольший общий делитель.
  14. Числа a и b называются взаимно простыми, если НОД этих чисел равен 1.
  15. Функция Эйлера φ(n) – функция, равная количеству натуральных чисел, меньших n и взаимно простых с ним.
  16.  
  17. */
  18.  
  19.  
  20. // Функция для проверки, является ли число простым
  21. bool isPrime(int n) {
  22.     if (n <= 1) return false;
  23.     if (n <= 3) return true;
  24.     if (n % 2 == 0 || n % 3 == 0) return false;
  25.     for (int i = 5; i * i <= n; i += 6) {
  26.         if (n % i == 0 || n % (i + 2) == 0) return false;
  27.     }
  28.     return true;
  29. }
  30.  
  31.  
  32. // Функция для вычисления наибольшего общего делителя двух чисел с использованием алгоритма Евклида
  33. int calculateNOD(int a, int b, int& x, int& y) {
  34.     //Базовый случай : если одно из чисел равно нулю, возвращаем другое число как НОД,
  35.     // устанавливаем значения коэффициентов расширенного алгоритма Евклида и завершаем рекурсию.
  36.     if (b == 0) {
  37.         x = 1;
  38.         y = 0;
  39.         return a;
  40.     }
  41.     // Рекурсивный случай: вычисляем НОД для чисел b и a % b.
  42.     //x1, y1 временные переменные для коэффициентов расширенного алгоритма Евклида
  43.     int x1, y1;
  44.     int nod = calculateNOD(b, a % b, x1, y1);
  45.     // Вычисляем коэффициенты расширенного алгоритма Евклида для чисел a и b.
  46.     x = y1;
  47.     y = x1 - (a / b) * y1;
  48.     // Возвращаем НОД(a, b)
  49.     return nod;
  50. }
  51.  
  52. // Функция для вычисления модулярного обратного 'publicKeyExponent' по модулю 'phi'
  53. // phi - это такое число x, что (publicKeyExponent * x) mod phi = 1.
  54.  
  55. int calculateModInverse(int publicKeyExponent, int phi) {
  56.     int x, y;
  57.     // Вычисляем наибольший общий делитель с использованием алгоритма Евклида
  58.     int nod = calculateNOD(publicKeyExponent, phi, x, y);
  59.     // Если НОД(publicKeyExponent, phi) не равен 1, то обратного значения не существует по модулю m
  60.     if (nod != 1) {
  61.         throw runtime_error("Обратное значение не существует");
  62.     }
  63.     else {
  64.         //(x % m + m) % m, чтобы результат был положительный(если х отриц)
  65.         return (x % phi + phi) % phi;
  66.     }
  67. }
  68.  
  69. // Функция для генерации открытого и закрытого ключей для шифрования RSA
  70.  
  71. void generateRSAKeys(int prime1, int prime2, int& publicKeyExponent, int& privateKeyExponent, int& modulus) {
  72.     // Вычисляем модуль как произведение двух простых чисел
  73.     modulus = prime1 * prime2;
  74.     int phi = (prime1 - 1) * (prime2 - 1);// Вычисляем значение функции Эйлера от модуля
  75.  
  76.     // Выбор открытого экспонента 'e'
  77.     publicKeyExponent = 2; // Начинаем с общего выбора для e
  78.     int x, y; // переменные для расширенного алгоритма Евклида
  79.  
  80.     // Пока НОД(publicKeyExponent, phi) не равен 1, увеличиваем publicKeyExponent.
  81.     while (calculateNOD(publicKeyExponent, phi, x, y) != 1) {
  82.         publicKeyExponent++;
  83.     }
  84.     // Вычисляем закрытый экспонент 'd' как модуль обратного 'e' по модулю phi
  85.     privateKeyExponent = calculateModInverse(publicKeyExponent, phi);
  86. }
  87.  
  88. // Функция для шифрования сообщения с использованием открытого ключа (e, n)
  89. int encrypt(int message, int publicKeyExponent, int modulus) {
  90.     int result = 1;
  91.     for (int i = 0; i < publicKeyExponent; i++) {
  92.         result = (result * message) % modulus;
  93.     }
  94.     return result;
  95. }
  96.  
  97. // Функция для дешифрования с использованием закрытого ключа (d, n)
  98. int decrypt(int ciphertext, int privateKeyExponent, int modulus) {
  99.     int result = 1;
  100.     for (int i = 0; i < privateKeyExponent; i++) {
  101.         result = (result * ciphertext) % modulus;
  102.     }
  103.     return result;
  104. }
  105.  
  106.  
  107. // Функция для факторизации числа
  108. void factorize(int n, int ciphertext, int publicKeyExponent) {
  109.     for (int i = 2; i <= n / 2; i++) {
  110.         if (n % i == 0 && isPrime(i) && isPrime(n / i)) {
  111.             //с помощью них можем попробовать узнать приватный ключ
  112.             cout << "Множители модуля, которые мы узнали с помощью факторизации: " << i << " и " << n / i << endl<<endl;
  113.             // Здесь вычисляем закрытый ключ
  114.             int prime1 = i;
  115.             int prime2 = n / i;
  116.             int modulus = prime1 * prime2;
  117.             int phi = (prime1 - 1) * (prime2 - 1);
  118.             int x, y;
  119.             int privateKeyExponent = calculateModInverse(publicKeyExponent, phi);
  120.  
  121.             //
  122.             cout << "Предполагаемый закрытый ключ (исходя из метода факторизации): {" << privateKeyExponent << ", " << modulus << "}" << std::endl;
  123.             //
  124.             cout << "Предполагаемое дешифрованное сообщение: " << decrypt(ciphertext, privateKeyExponent, modulus) << endl;
  125.             return;
  126.         }
  127.     }
  128.     cout << "Не удалось выполнить факторизацию." << std::endl;
  129. }
  130.  
  131.  
  132. // Функция для хэширования цифрового сообщения
  133. //фиксированная длина✅
  134. //Хеш должен быть быстр в вычислении и обладать свойством нереверсивности, то есть невозможности восстановления исходных данных из хеш - кода✅
  135. int hashMessage(int message) {
  136.     // Преобразуем сообщение в его строковое представление
  137.     string messageStr = to_string(message);
  138.     // Вычисляем сумму цифр сообщения
  139.     int sum = 0;
  140.     for (char digit : messageStr) {
  141.         sum += (digit - '0'); // Преобразуем символ в число и добавляем к сумме
  142.     }
  143.  
  144.     // Приводим сумму к фиксированной длине 2
  145.     while (sum >= 100) {
  146.         sum = (sum / 10) + (sum % 10); // Суммируем цифры числа
  147.     }
  148.     while (sum < 10) {
  149.         sum=sum*sum;
  150.     }
  151.     return sum;
  152. }
  153.  
  154. int main() {
  155.     setlocale(LC_ALL, "Russian");
  156.     // два простых числа
  157.     int prime1 = 11;
  158.     int prime2 = 13;
  159.     //cin >> prime1;
  160.     //cin >> prime2;
  161.     int modulus, publicKeyExponent, privateKeyExponent;
  162.  
  163.     // Генерируем открытый и закрытый ключи для шифрования RSA
  164.     generateRSAKeys(prime1, prime2, publicKeyExponent, privateKeyExponent, modulus);
  165.  
  166.     cout << "Открытый ключ: {" << publicKeyExponent << ", " << modulus << "}" << endl;
  167.     cout << "Закрытый ключ: {" << privateKeyExponent << ", " << modulus << "}" << endl;
  168.  
  169.     // сообщение для шифрования, оно должно быть меньше 143(тк есть зависимость от модуля)для других чисел-другие ограничения
  170.     int message = 141;
  171.  
  172.     // Шифруем хешированное сообщение
  173.     int hashedMessage = hashMessage(message);
  174.     cout << "Хэш сообщения: " << hashedMessage << endl;
  175.  
  176.     // Шифруем сообщение
  177.     int ciphertext = encrypt(hashedMessage, publicKeyExponent, modulus);
  178.     // Дешифруем
  179.     int decryptedMessage = decrypt(ciphertext, privateKeyExponent, modulus);
  180.  
  181.     // Выводим исходное сообщение
  182.     cout << "Исходное сообщение: " << message << endl<<endl;
  183.     factorize(modulus, ciphertext, publicKeyExponent);
  184.  
  185.     // Выводим зашифрованное хешированное сообщение
  186.     cout <<endl<< "Зашифрованное хешированное сообщение: " << ciphertext << endl;
  187.     // Выводим дешифрованное сообщение
  188.     cout << "Дешифрованное хешированное сообщение: " << decryptedMessage << endl << endl;
  189.  
  190.     // Проверяем, что расшифрованный хэш соответствует исходному хэшу
  191.     if (decryptedMessage == hashedMessage) {
  192.         cout << "Расшифрованный хэш соответствует исходному хэшу. Целостность данных подтверждена." << endl;
  193.     }
  194.     else {
  195.         cout << "Расшифрованный хэш не соответствует исходному хэшу. Целостность данных нарушена." << endl;
  196.     }
  197.  
  198.     return 0;
  199. }
  200.  
Tags: hack_rsa
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement