RSA шифрование и расшифровка сообщения - C (СИ)
Формулировка задачи:
Написал небольшу програмку для шифрования и расшифровывания сообщений.
1 - Программа должна сгенерировать random prime number
2 - Проверить - prime or not
3 - Создать ключи используя наши два сгенерированные номера и плюс добавляем еще один (сами)
4 - Зашифровать сообщение и передать в файл
5 - Расшифровать это же сообщение и тоже передать в файл.
Все работает, составлен примитивный диалог, но как доходит до шифрования и расшифровки - прога начинает выдавать фигню, хотя вроде шифрование проходит нормально.
Код
Запускаем
prob_01.jpg
Вроде все нормально, но откуда отрицательное число?
prob_02.jpg
Результат....
Где недочеты??? По возможности выправите код.... устал уже с прогой.
#include<stdio.h> // main labrary
#include<stdlib.h> // required for randomize() and random()
#include<conio.h> // required _getch() - pause
#include<math.h> // Just in case - I will use diff math testes
#include<time.h>
#include <string.h>
#include <iostream>
// ..............................................................................
//using namespace std;
//void init_mm( );
//int number_range( int from, int to );
//int number_mm( void );
//int getprimeNumber(int From, int To, bool checkIt);
//bool isprime(int num);
//void generatePN();
//void startProg();
//bool checkForErrors(int L, int H);
//static int rgiState[2+55]; // leave this alone
// .................................................................................
int phi, m, n, e, i, j, r1, r2, p, q, d, ch;
long long int square(long long int a);
long long int BigMod(int M, int E, int N);
void encrypt(int l, int E, int N);
void decrypt(int E, int N);
long long int BigMod(int b, int p, int m)
{
if(p == 0)
return 1;
else if(p%2 == 0)
return square(BigMod(b, p/2, m)) % m;
else
return (((b % m) * BigMod(b, p-1, m)) % m);
}
long long int square(long long a)
{
return a*a;
}
void encrypt(int m, int e, int n)
{
FILE * fp;
fp = fopen("cipher_text.txt", "a");
int c = BigMod (m, e, n);
printf("%d ", c) ;
fprintf(fp,"%d ", c);
fclose(fp);
}
void decrypt(int d, int n)
{
FILE * fp;
fp = fopen("plaine_text.txt", "a");
while(1)
{
int c;
fscanf(fp,"%d", &c);
if(c==-1) break;
int m=BigMod(c, d, n);
printf("%c", m);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
int IsPrime(unsigned int number)
{
if (number <= 1) return 0; // zero and one are not prime
unsigned int i;
for (i=2; i*i<=number; i++)
{
if (number % i == 0) return 0;
}
return 1;
}
void generate_two_primes() // Start to generate two prime numbers N times (is need)
{
int seed = time(NULL);
srand(seed);
unsigned int r;
printf("Generating first number ");
do
{
printf(".");
r = rand() % 1000; // Genertate random number as r
}
while(IsPrime(r) == 0);
r1 = r;
printf("\nGenerating second number ");
do
{
printf(".");
r = rand() % 1000; // Genertate random number as r
}
while(IsPrime(r) == 0);
r2 = r;
}
////////////////////////////////////////////////////////////////////////////////////
int main(void)
{
// ..................................... Generate a 2 random numbers .........................................
printf("\n\nAwaiting, the random numbers generate...\n\nPleese click Enter to generate \n\n"); // Start dialog
_getch(); // Create pause ..
generate_two_primes();
// .................................... Finish random numbers .................................................
// .................................... Check on the Prime number ..............................................
printf(".........................................................................\n\n");
printf("For check first number %d and second number %d\nas a Prime Number please click Enter\n\n", r1, r2);
_getch(); // Create pause
j = 2, ch = 0;
// ...................... Check First number ............ //
while(j <= r1/2)
{
if(r1 % j == 0)
{
ch = 1;
break;
}
else
{
j++;
}
}
if(ch == 0)
{
printf("The number %d is prime\n\n", r1);
}
else
{
printf("The number %d is not prime\n\n", r1);
}
// ...................... Check second number .............. //
while(j <= r2 / 2)
{
if(r2 % j == 0)
{
ch = 1;
break;
}
else
{
j++;
}
}
if(ch == 0)
{
printf("The number %d is prime\n\n", r2);
}
else
{
printf("The number %d is not prime\n\n", r2);
}
printf(".........................................................................\n\n");
// ....................................... Finish check Prime number .............................
// ............................ Work with Public and Privat key ..................................
printf("We have a two large numbers %d and %d\n", r1, r2);
printf("Now we will calculate Public key and Privat key, please type ANY number\n\n");
// ................... Change integers on the formula letters
p = r1; // Change letter on the standard letter for furmula p
q = r2; // Change letter on the standard letter for furmula q
n = p * q; // Calculate n
// .......................................................... Change letters
scanf("%d", &e); // Add more one number
phi = (p-1)*(q-1);
// Putput result on calculation
printf("\nPublic key ( e , n ) : ( %d %d )\n\nPlease click Enter to calculate Privat key\n\n", e, n);
_getch(); // Create pause
int d, RES = -1;
for (d = 1;; d++)
{
RES = (d*e) % phi;
if (RES == 1) break;
}
printf("Private Key ( d ) : ( %d )\n", d);
printf("\n\nPlease click Enter for cont...\n\n");
_getch(); // Create pause
// ........................................... Finish genertae Public and Privat key ............
printf("Please input your string here : ");
char arr[1000000];
fflush(stdin);
gets(arr);
int i;
FILE * fp=fopen("plaine_text.txt", "a");
fclose(fp);
for(i = 0; arr[i]; i++)
{
int ASCII=arr[i];
encrypt(ASCII, e, n);
}
printf("\n");
FILE *fpp = fopen("cipher_text.txt", "a");
//fprintf(fp, "-1");
fclose(fpp);
decrypt(d, n);
getchar();
}Решение задачи: «RSA шифрование и расшифровка сообщения»
textual
Листинг программы
#include<stdio.h> // main labrary
#include<stdlib.h> // required for randomize() and random()
#include<conio.h> // required _getch() - pause
#include<math.h> // Just in case - I will use diff math testes
#include<time.h>
#include<string.h>
#include<iostream>
// .................................................................................
long phi, m, n, e, i, j, r1, r2, p, q, d, ch;
long long int square(long long int a);
long long int BigMod(int M, int E, int N);
void encrypt(int l, int E, int N);
void decrypt(int E, int N);
long long int BigMod(int b, int p, int m)
{
if(p == 0)
return 1;
else if(p%2 == 0)
return square(BigMod(b, p/2, m)) % m;
else
return (((b % m) * BigMod(b, p-1, m)) % m);
}
long long int square(long long a)
{
return a*a;
}
void encrypt(int m, int e, int n)
{
FILE * fp;
fp = fopen("cipher_text.txt", "a");
int c = BigMod (m, e, n);
printf("%d ", c) ;
fprintf(fp,"%d ", c);
fclose(fp);
}
void decrypt(int d, int n)
{
FILE * fp;
fp = fopen("plaine_text.txt", "a");
while(1)
{
int c;
fscanf(fp,"%d", &c);
if(c==-1) break;
int m=BigMod(c, d, n);
printf("%c", m);
}
}
int gcd(int a, int b)
{
int r;
while (b != 0)
{
r = a % b;
a = b;
b = r;
}
return a;
}
int getD(int _pq, int e)
{
int d = 0;
int pq = _pq;
bool found = false;
int first = e;
int second = pq;
int count = 1;
while (found == false)
{
first = first += e;
count++;
if ((first - second) == 1)
{
found = true;
}
if (first > second)
{
second = second += pq;
}
}
d = count;
count = 0;
return d;
}
int IsPrime(unsigned int number)
{
if (number <= 1) return 0; // zero and one are not prime
unsigned int i;
for (i=2; i*i<=number; i++)
{
if (number % i == 0) return 0;
}
return 1;
}
void generate_two_primes() // Start to generate two prime numbers N times (is need)
{
int seed = time(NULL);
srand(seed);
unsigned int r;
printf("Generating First number ");
do
{
printf(".");
r = rand() % 1000; // Genertate random number as r
}
while(IsPrime(r) == 0);
r1 = r;
printf("\nGenerating Second number ");
do
{
printf(".");
r = rand() % 1000; // Genertate random number as r
}
while(IsPrime(r) == 0);
r2 = r;
}
void second_check_prime()
{
// .................................... Check on the Prime number
..............................................
printf(".........................................................................\n\n");
printf("For check first number %d and second number %d\nas a Prime Number please click Enter\n\n",
r1, r2);
_getch(); // Create pause
j = 2, ch = 0;
// ...................... Check First number ............ //
while(j <= r1/2)
{
if(r1 % j == 0)
{
ch = 1;
break;
}
else
{
j++;
}
}
if(ch == 0)
{
printf("The number %d is prime\n\n", r1);
}
else
{
printf("The number %d is not prime\n\n", r1);
}
// ...................... Check second number .............. //
while(j <= r2 / 2)
{
if(r2 % j == 0)
{
ch = 1;
break;
}
else
{
j++;
}
}
if(ch == 0)
{
printf("The number %d is prime\n\n", r2);
}
else
{
printf("The number %d is not prime\n\n", r2);
}
printf(".........................................................................\n\n");
// ....................................... Finish check Prime number .............................
}
int main(void)
{
// ..................................... Generate a 2 random numbers
......................................... //
printf("\n\nAwaiting, the random numbers generate...\n\nPleese click Enter to generate \n\n"); //
Start dialog
_getch(); // ........................................................
Create pause //
generate_two_primes();
// .................................... Finish random numbers
................................................. //
// .................................... Show - the two numbers is Prime
....................................... //
second_check_prime();
//
...........................................................................................................
. //
// ............................ Work with Public and Privat key
............................................... //
// ............................ Dialog
........................................................................ //
printf("We have a two large numbers %d and %d\n", r1, r2);
printf("Now we will calculate the arguments required for the our encription.");
printf("\nPlease click ENTER and continue ... ");
_getch(); // ........................................................
Create pause //
//
...........................................................................................................
. //
// ................... Change integers on the formula letters
................................................. //
p = r1; // Change letter on the standard letter for furmula p
q = r2; // Change letter on the standard letter for furmula q
int n = p * q; // Calculate n
//
...........................................................................................................
. //
// ................................... Start work with P, Q, N, PHI, E ect
.................................... //
printf("\n\nWe have:\n p = %d (As First prime number) \n q = %d (As Second prime number) \n n = %d
(as result n = p * q) \n", p, q, n);
int phi = (p-1) * (q-1);
printf("\nThe PHI = %d (As (p-1) * (q-1)) \n", phi);
int e;
for (int i = 3; i < phi; i++)
{
if (gcd(i, phi) == 1)
{
e = i;
break;
}
}
printf("\n The e = %d (As calculation gcd)", e);
printf("\n\nPlease click ENTER to show Public and Privat keys\n\n");
_getch(); // ........................................................
Create pause //
// .................................. Finish work with arguments
.............................................. //
// .................................. Show Privat and Publick key
............................................. //
printf("*************************************************************************");
printf("\nPublick Keys: %d and %d \n", n, e);
int d = getD(phi, e);
printf("\n d = %d \n", d);
printf("\nPrivate Keys: %d and %d \n", n, d);
printf("*************************************************************************");
printf("\n\nPlease click Enter for cont...\n\n");
_getch(); // .........................................................
Create pause //
// ........................................... Finish genertae Public and Privat key
........................... //
//.........................................................................................................
..... //
printf("Please input your string here : ");
char arr[1000000];
fflush(stdin);
gets(arr);
int i;
FILE * fp=fopen("plaine_text.txt", "a");
fclose(fp);
for(i = 0; arr[i]; i++)
{
int ASCII=arr[i];
encrypt(ASCII, e, n);
}
printf("\n");
FILE *fpp = fopen("cipher_text.txt", "a");
//fprintf(fp, "-1");
fclose(fpp);
decrypt(d, n);
getchar();
}