본문 바로가기

Incognito

RSA 암호 알고리즘

RSA 암호 알고리즘

공개키 암호시스템의 하나

 

다양한 분야에서 가장 보편적으로 사용되는 암호 알고리즘이다.

 

아주 큰 두 소수의 곱으로 이루어진 합성수를 인수분해하기 어렵다는 인수분해 문제의 어려움에 기반한 안전성을 가진다!

 

많은 데이터를 여러 번 암호화해야 하는 네트워크 통신에서는 잘 사용되지 않는다.

(많은 연산을 필요로 하기 때문)

 

 

 

 

 

RSA 암호 알고리즘은 두 개의 키를 사용한다.

- 공개키 (Public Key)

- 개인키 (Private Key)

 

공개키는 모든 사용자에게 공개되며, 평문을 암호화할 때 사용한다.

 

개인키는 타인에게 노출되어서는 안 되며, 공개키로 암호화된 암호문을 복호화할 때 사용한다.

 

 

 

 

 

오일러 정리

서로소인 양의 정수 m이 아래의 식을 만족한다는 정리

 

 

오일러 파이 함수 (Euler's phi function)

임의의 n 이하의 양의 정수 중 n과 서로소인 수의 개수

 

 

 

example 1.

6 이하의 양의 정수 중 6과 서로소인 수: 1, 5

φ(6) = 2

소수 p의 경우 1부터 p-1까지 모두 p와 서로소이기 때문에 φ(p) = p-1

 

 

 

 

 

키 생성

1. 임의의 두 소수 p, q 선택 (1024 비트 이상에서 비트 길이가 같은 수)

2. n= p x q

 

φ(n) = p x q - p - q + 1 = (p-1)(q-1)

 

3. φ(n)보다 작은 수 중 φ(n)과 서로소인 e 선택

4. d 구하기

 

n, e는 공개키

d는 개인키

 

 

 

 

 

[c++ 코드 예제]

 

#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;

int p = 0, q = 0, n, t, flag, e[100], d[100], temp[100], j, m[100], en[100], i;
char msg[100];

int prand() { //난수 생성 (소수)
	int j;
	srand((unsigned)time(NULL));
	while (1) {
		j = (rand() % 98 + 2);
		if (j == 2)
			return j;
		for (int I = 2; I < j; I++) {
			if (j % I == 0)
				break;
			if ((I + 1) == j)
				return j;
		}
	}
}
int prime(int pr) { //p, q에 저장
	int i;
	j = sqrtl(pr);
	for (i = 2; i <= j; i++)
		if (pr % i == 0) //나머지가 0일 경우 소수가 아님
			return 0;
	return 1;
}
int cd(int x) {
	int k = 1;
	while (1) {
		k = k + t;
		if (k % x == 0)
			return(k / x);
	}
}
void ce() {
	int k;
	k = 0;
	for (i = 2; i < t; i++) {
		if (t % i == 0)
			continue;
		flag = prime(i);
		if (flag == 1 && i != p && i != q) {
			e[k] = i;
			flag = cd(e[k]);
			if (flag > 0) {
				d[k] = flag;
				k++;
			}
			if (k == 99)
				break;
		}
	}
}
void encrypt() { //암호화
	int pt, ct, key = e[0], k, len;
	i = 0;
	len = strlen(msg);
	while (i != len) {
		pt = m[i];
		pt = pt - 96;
		k = 1;
		for (j = 0; j < key; j++) {
			k = k * pt;
			k = k % n;
		}
		temp[i] = k;
		ct = k + 96;
		en[i] = ct;
		i++;
	}
	en[i] = -1;
	cout << "\nTHE ENCRYPTED MESSAGE IS ";
	for (i = 0; en[i] != -1; i++)
		cout << (char)en[i];
	cout << endl;
}
void decrypt() { //복호화
	int pt, ct, key = d[0], k;
	i = 0;
	while (en[i] != -1) {
		ct = temp[i];
		k = 1;
		for (j = 0; j < key; j++) {
			k = k * ct;
			k = k % n;
		}
		pt = k + 96;
		m[i] = pt;
		i++;
	}
	m[i] = -1;
	cout << "THE DECRYPTED MESSAGE IS ";
	for (i = 0; m[i] != -1; i++)
		cout << (char)m[i];
	cout << endl;
}
int main() {
	cout << "First Number: ";
	p = prand();
	cout << p << endl;
	cout << "Second Number: ";
	while (1) {
		q = prand();
		if (q != p)
			break;
	}
	cout << q << endl;
	cout << "ENTER MESSAGE: ";
	fflush(stdin);
	cin >> msg;
	for (i = 0; msg[i] != NULL; i++)
		m[i] = msg[i];
	n = p * q;
	t = (p - 1) * (q - 1);
	ce();
	encrypt();
	decrypt();
	return 0;
}

참고: https://coyagi.tistory.com/entry/c-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-RSA

 

 

 

 

 

[코드 실행]

 

 

'Incognito' 카테고리의 다른 글

일회용 패드 & 블록 암호  (0) 2022.10.22
고전 암호  (0) 2022.10.09
암호학 퀴즈  (0) 2022.09.11
[CryptoHack] ASCII  (0) 2022.08.10
[CryptoHack] Network Attacks  (0) 2022.08.07