[컴퓨터보안]일회용 패드 c언어 구현
기타/보안

[컴퓨터보안]일회용 패드 c언어 구현

728x90

1) 일회용 패드란?

 

일회용패드(one-time pad)는 전사공격에서 키 공간을 모두 탐색하더라도 해독할 수 없는 암호로 키를 딱 한번 쓰도록 설계된 암호체계를 의미합니다.

 

이 암호 체계의 핵심은 키의 조건XOR이라는 이진수 연산 방식에 있습니다.

 

● 키의 조건

- 키는 반드시 1회만 사용되어야 한다.
- 키는 반드시 랜덤해야 한다.
- 키는 평문과 길이가 같아야 한다.


● XOR 연산
- 평문과 키를 XOR 연산하여 암호문 생성

- 암호문과 키를 XOR 연산하여 평문 생성

일회용 패드의 암호화/복호화 원리

 

2) 일회용 패드 구현

프로그램 구조도

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
 
#define MAXSIZE 9
 
//step1. 8개의 문자열을 평문으로 입력받기
char* inputPlainText() {
    static char inputText[MAXSIZE];
 
    printf("\n1) 8개의 문자열을 평문으로 입력받기\n\n");
    while (1) {
        printf("8글자의 평문을 입력하세요: \n>> ");
        scanf("%s", inputText);
        if (strlen(inputText) != 8) {
            printf("error) 글자 수 입력 오류\n");
            printf("8글자가 아닙니다.\n");
            printf("--------------------------------------------------------------------------------------------------------\n");
        }
        else {
            break;
        }
    }
    //printf("%s", inputText);
    printf("\n입력된 평문      ");
    
    for (int i = 0; i < 8; i++) {
        printf("|    %c    ", inputText[i]);
    }
    
    printf("\n--------------------------------------------------------------------------------------------------------\n");
    return inputText;
}
 
 
int ASCII_to_binary(int ASCII) {
    int result = 0;
    for (int i = 1; ASCII > 0; i *= 10) {
        int binary = ASCII % 2;
        result += binary * i;
        ASCII /= 2;
    }
    return result;
}
 
void printBinary(int* encryptionKey) {
    for (int i = 0; i < 8; i++) {
        if (encryptionKey[i] < 10) {
            printf("| 0000000%d ", encryptionKey[i]);
        }
        else if (encryptionKey[i] < 100) {
            printf("| 000000%d ", encryptionKey[i]);
        }
        else if (encryptionKey[i] < 1000) {
            printf("| 00000%d ", encryptionKey[i]);
        }
        else if (encryptionKey[i] < 10000) {
            printf("| 0000%d ", encryptionKey[i]);
        }
        else if (encryptionKey[i] < 100000) {
            printf("| 000%d ", encryptionKey[i]);
        }
        else if (encryptionKey[i] < 1000000) {
            printf("| 00%d ", encryptionKey[i]);
        }
        else if (encryptionKey[i] < 10000000) {
            printf("| 0%d ", encryptionKey[i]);
        }
        else {
            printf("| %d ", encryptionKey[i]);
        }
    }
}
 
//step2. 아스키 코드를 기준으로 부호화 (64 bit)
int* encodingASCII(char* plainText) {
    static int ASCIICode[8];
    printf("\n2) 아스키 코드를 기준으로 부호화 (64 bit)\n\n");
    
    printf("10진수로 변환    ");
    for (int i = 0; i < 8; i++) {
        int ASCII = (int)plainText[i];
        printf("|   %d   ", ASCII);
        ASCIICode[i]= ASCII_to_binary(ASCII);
    }
    printf("\n--------------------------------------------------------------------------------------------------------\n");
    printf("2진수로 변환     ");
    printBinary(ASCIICode);
    
    printf("\n--------------------------------------------------------------------------------------------------------\n");
    return ASCIICode;
    
}
 
 
//step3, step5 암호화 키/복호화 키 랜덤 설정(64 bit)
int* setRandomKey(int keyType) {
    static int encryptionKey[8];
    int binaryEncryptionKey[8];
    srand(time(NULL));
    if (keyType == 1) {
        printf("\n3) 암호화 키 설정(64 bit)\n\n");
    }
    
    for (int i = 0; i < 8; i++) {
        encryptionKey[i] = rand() % 128;
        binaryEncryptionKey[i] = ASCII_to_binary(encryptionKey[i]);
    }
    if (keyType == 1) {
        printf("암호화키 생성    ");
    }
    else if (keyType == 2) {
        printf("복호화키 생성    ");
    }
    
    for (int i = 0; i < 8; i++) {
        printf("|    %d    ", encryptionKey[i]);
    }
    printf("\n--------------------------------------------------------------------------------------------------------\n");
    printf("2진수로 변환     ");
    printBinary(binaryEncryptionKey);
    printf("\n--------------------------------------------------------------------------------------------------------\n");
 
    return encryptionKey;
}
 
 
//step4. XOR 연산을 통해 평문을 암호화
int* plainEncryption(char* plainText, int* encryptionKey) {
    int cryptogram[8];
    static int binaryCryptogram[8];
    printf("\n4. XOR 연산을 통해 평문을 암호화\n\n");
 
    for (int i = 0; i < 8; i++) {
        binaryCryptogram[i] = plainText[i] ^ encryptionKey[i];
        cryptogram[i] = ASCII_to_binary(binaryCryptogram[i]);
    }
    printf("XOR 연산(암호화) ");
    printBinary(cryptogram);
    printf("\n--------------------------------------------------------------------------------------------------------\n");
 
    return binaryCryptogram;
}
 
//step6. XOR 연산을 통해 암호문을 평문화
int* cryptogramPlain(int* encryption, int* encryptionKey) {
    static int decryption[8];
    int plain[8];
    printf("\n6. XOR 연산을 통해 암호문을 평문화\n\n");
    for (int i = 0; i < 8; i++) {
        plain[i] = encryption[i] ^ encryptionKey[i];
        decryption[i] = ASCII_to_binary(plain[i]);
    }
    printf("XOR 연산(복호화) ");
    printBinary(decryption);
    printf("\n--------------------------------------------------------------------------------------------------------\n");
    printf("복호화된 평문    ");
    for (int i = 0; i < 8; i++) {
        printf("|    %c    ", plain[i]);
    }
    printf("\n--------------------------------------------------------------------------------------------------------\n");
 
    return decryption;
}
 
int main() {
    //일회용 패드 구현
    printf("<일회용 패드 구현>\n");
    printf("--------------------------------------------------------------------------------------------------------\n");
 
    //step1. 8개의 문자열을 평문으로 입력받기
    char* plainText = inputPlainText();
    
    //step2. 아스키 코드를 기준으로 부호화 (64 bit)
    int* ASCIICode = encodingASCII(plainText);
 
    //step3. 암호화 키 설정(64 bit)
    int* encryptionKey = setRandomKey(1);
    
    //step4. XOR 연산을 통해 평문을 암호화
    int* encryption = plainEncryption(plainText, encryptionKey);
    
    //step5. 복호화 키 설정(64bit)
    printf("\n5) 복호화 키 설정(64 bit)\n\n");
    int num;
    while (1) {
        printf("암호화키와 동일한 복호화 키를 사용하시겠습니까?(Yes:1, No:2)\n >>");
        scanf(" %d"&num);
        if (num == 1) {
            int* decryption = cryptogramPlain(encryption, encryptionKey);
            break;
        }
        else if (num == 2) {
            int* decryptionKey = setRandomKey(2);
            int* decryption = cryptogramPlain(encryption, decryptionKey);
            break;
        }
        else {
            printf("error) 입력값 오류\n");
            printf("Yes(1), No(2) 중에 선택해주세요.\n");
            printf("--------------------------------------------------------------------------------------------------------\n");
        }
    }
 
    return 0;
}
cs

 

3) 실행 결과

 

암호화키와 복호화키가 같을 경우

 

암호화키와 복호화키가 다를 경우

 

기타 오류 처리

글자 수 입력 오류 처리
숫자 입력 오류 처리

 

728x90