Russian Qt Forum
Ноябрь 23, 2024, 18:20 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Демонстрация работы алгоритма шифрования RSA  (Прочитано 4259 раз)
alexu007
Чайник
*
Offline Offline

Сообщений: 58


Просмотр профиля
« : Июль 30, 2022, 09:33 »

Демонстрация работы алгоритма шифрования RSA, без использования длинной арифметики - длина ключа влезает в quint64.
 
Работа с программой:
1. Запускаем две копии программы - Алиса и Боб.
2. В каждой копии получаем открытый и закрытый ключи.
3. Обмениваемся открытыми ключами.
4. Алиса шифрует своё сообщение с помощью открытого ключа Боба.
5. Полученный зашифрованный текст Алиса отправляет Бобу.
6. Боб расшифровывает послание Алисы с помошью своего закрытого ключа.
7. В обратную сторону (от Боба к Алисе) то же самое.

Записан
alexu007
Чайник
*
Offline Offline

Сообщений: 58


Просмотр профиля
« Ответ #1 : Июль 30, 2022, 09:39 »

Код
C++ (Qt)
#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include <qmath.h>
#include <QTime>
#include <QRandomGenerator>
#include <QTextCodec>
 
 
qint64 make_Key(qint64, qint64);
quint64 make_RSA(quint64, quint64, quint64);
quint64 makePrimeDigit();
 
bool isPrime(quint64);
 
 
namespace Ui {
class Widget;
}
 
class Widget : public QWidget
{
   Q_OBJECT
 
public:
   explicit Widget(QWidget *parent = 0);
   ~Widget();
 
private:
   Ui::Widget *ui;
 
public slots:
 
   void press_pbtn_01();
   void press_pbtn_02();
   void press_pbtn_03();
   void press_pbtn_04();
};
 
#endif // WIDGET_H


Код
C++ (Qt)
#include "widget.h"
#include "ui_widget.h"
 
 
 
 
 
Widget::Widget(QWidget *parent) :
   QWidget(parent),
   ui(new Ui::Widget)
{
   ui->setupUi(this);
 
   // инициализация ГСЧ
   qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
 
   QObject::connect(ui->pbtn_01,SIGNAL(clicked()),this,SLOT(press_pbtn_01()));
   QObject::connect(ui->pbtn_02,SIGNAL(clicked()),this,SLOT(press_pbtn_02()));
   QObject::connect(ui->pbtn_03,SIGNAL(clicked()),this,SLOT(press_pbtn_03()));
   QObject::connect(ui->pbtn_04,SIGNAL(clicked()),this,SLOT(press_pbtn_04()));
}
 
 
 
 
 
Widget::~Widget()
{
   delete ui;
}
 
 
 
 
 
// кнопка "получить"
void Widget::press_pbtn_01()
{
   quint64 easy1, easy2;
   quint64 modul = 0xF000000000000000;
 
   while(modul > 0x7FFFFFFFFFFFFFFF)
   {
       easy1 = makePrimeDigit();
       easy2 = makePrimeDigit();
       modul = easy1 * easy2;
   }
 
   //easy1 = 4146278621;
   //easy2 = 1970034377;
   //modul = easy1 * easy2;
 
   ui->lineEdit_03->setText(QString::number(easy1));
   ui->lineEdit_04->setText(QString::number(easy2));
 
   // Простое число Мерсенна
   // обычно используется в RSA в виде открытой экспоненты для увеличения производительности
   quint64 open_kl = 65537;
 
   quint64 m = (easy1 - 1) * (easy2 - 1);
   quint64 close_kl = make_Key(open_kl, m);
 
   ui->lineEdit_06->setText(QString::number(modul));
   ui->lineEdit_07->setText(QString::number(close_kl));
}
 
 
 
 
// кнопка шифровать RSA
void Widget::press_pbtn_02()
{
   quint64 open_kl, modul, rsa;
   quint64 buf;
 
   QString str1, str2;
   QStringList lstr;
   QStringList lstr2;
   QByteArray barr;
 
   bool ok;
 
   QTextCodec *codec = QTextCodec::codecForName("UTF-8");
 
 
   str1 = ui->textEdit_01->toPlainText();
   barr = codec->fromUnicode(str1);
 
 
   barr.prepend(qrand() % 255 + 1);
 
   int cxb = barr.size();
   int cxi = 0;
 
 
   // простое шифрование байтовой последовательности
   for(int i = 1; i < cxb; i++)
   {
       barr[i] = barr.at(i-1) ^ barr.at(i);
   }
 
 
   // чтение
   while(cxb)
   {
       buf = 0;
       for(int i = 0; i < 7; i++)
       {
           cxb--;
           quint8 qw = barr.at(cxi++);
           buf |= qw;
           if(i == 6 || !cxb) break;
           buf <<= 8;
       }
 
       str1 = QString::number(buf, 16);
       lstr << str1;
 
       //ui->textEdit_01->append(str1);
   }
 
   // шифрование
   ui->textEdit_02->append("");
   lstr2.clear();
 
   open_kl = 65537;
 
   str1 = ui->lineEdit_02->text();
   modul = str1.toULongLong();
 
   for(int i = 0; i < lstr.size(); i++)
   {
       str1 = lstr.at(i);
       quint64 x = str1.toULongLong(&ok, 16);
       rsa = make_RSA(x, open_kl, modul);
 
       str2 = QString::number(rsa, 16);
       if(str2 == "0") continue;
 
       lstr2 << str2;
       ui->textEdit_02->append(str2);
   }
}
 
 
 
 
 
// кнопка дешифровать RSA
void Widget::press_pbtn_03()
{
 
   quint64 modul, rsa;
   QString str1, str2;
   QStringList lstr;
   QStringList lstr2;
   QByteArray barr;
   bool ok;
 
   QTextCodec *codec = QTextCodec::codecForName("UTF-8");
 
 
   str1 = ui->textEdit_02->toPlainText();
   lstr2 = str1.split(QRegExp("[\n]"),QString::SkipEmptyParts);
 
   str1 = ui->lineEdit_06->text();
   modul = str1.toULongLong();
 
 
   //ui->textEdit_02->append("");
   //lstr.clear();
 
   //дешифрование
   str1 = ui->lineEdit_07->text();
   quint64 close_kl = str1.toULongLong();
 
   for(int i = 0; i < lstr2.size(); i++)
   {
       str1 = lstr2.at(i);
       quint64 x = str1.toULongLong(&ok, 16);
       rsa = make_RSA(x, close_kl, modul);
 
       str2 = QString::number(rsa, 16);
 
       if(str2.length() % 2) str2.prepend("0");
       lstr << str2;
 
       //ui->textEdit_02->append(str2);
   }
 
   // формирование строки
   for(int i = 0; i < lstr.size(); i++)
   {
       str1 = lstr.at(i);
 
       for(int j = 0; j < 14; j+=2)
       {
 
           if(str1.length() == 1)
           {
               str2 = "0";
               str2 += str1[j+1];
           }
 
           else
           {
               str2 = str1[j];
               str2 += str1[j+1];
           }
 
           quint8 k = str2.toInt(&ok, 16);
           if(k > 0) barr.append(k);
       }
   }
 
 
   // простое дешифрование байтовой последовательности
   for(int i = barr.size()-1; i > 0; i--)
   {
       barr[i] = barr.at(i-1) ^ barr.at(i);
   }
 
   barr.remove(0, 1);
 
   QString str = codec->toUnicode(barr);
   str.remove(QChar(0));
   ui->textEdit_01->append(str);
 
}
 
 
 
 
 
// кнопка clear
void Widget::press_pbtn_04()
{
   ui->textEdit_01->clear();
   ui->textEdit_02->clear();
}
 
 
 
 
// расширенный алгоритм Евклида
quint64 extended_evclid(quint64 a, quint64 m)
{
   quint64 q, r, x, x1, x2;
 
   x2 = 1;
   x1 = 0;
 
   while (m > 0)
   {
       q = a / m;
       r = a - q * m;
       a = m;
       m = r;
 
       x = x2 - q * x1;
       x2 = x1;
       x1 = x;
 }
 
return x2;
}
 
 
 
 
// обратное по модулю
qint64 make_Key(qint64 a, qint64 m)
{
   qint64 x = extended_evclid(a, m);
   x = (x % m + m) % m;
 
   return x;
}
 
 
 
 
 
quint64 sum_mod (quint64 x, quint64 y, quint64 m)
{
   if(m - x > y) return  x + y;
   return  y - (m - x);
}
 
 
 
 
 
quint64 mul_mod(quint64 x, quint64 y, quint64 m)
{
   quint64 tmp;
   quint64 res = 0 ;
 
   if(x > y)
   {
     tmp = x ;
     x = y;
     y = tmp;
   }
 
   while(x)
   {
     if(x & 1) res = sum_mod(res, y, m);
 
     y  = sum_mod(y , y , m);
     x >>= 1;
   }
 
return  res ;
}
 
 
 
 
 
quint64 make_RSA(quint64 x, quint64 n, quint64 m)
{
   quint64 res = 1 ;
 
   while(n)
   {
       if(n & 1) res = mul_mod(res, x, m);
 
       x = mul_mod(x, x, m);
       n >>= 1;
   }
 
return res  ;
}
 
 
 
 
 
bool isPrime(quint64 a)
{
   quint64 x;
   quint64 n = sqrt(a)/6 + 1;
 
   if(a == 2) return true;
   if(a == 3) return true;
 
   if(!(a % 2)) return false;
   if(!(a % 3)) return false;
 
   for(quint64 i = 1; i < n; i++)
   {
       x = 6 * i;
       if(!(a % (x-1))) return false;
       if(!(a % (x+1))) return false;
   }
 
   return true;
}
 
 
 
 
// синтез простого числа
quint64 makePrimeDigit()
{
   quint32 a = 0x80000000;
   quint32 b = 0xfffffff0;
   quint64 x = QRandomGenerator::global()->bounded(a, b);
 
   if(!(x % 2)) x++;
 
   while(!isPrime(x))
   {
       x += 2;
   }
 
   return x;
}
Записан
alexu007
Чайник
*
Offline Offline

Сообщений: 58


Просмотр профиля
« Ответ #2 : Август 07, 2022, 12:49 »

Проект:

Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.389 секунд. Запросов: 22.