file_encrypt_v2.c

Download
c 327 lines 9.3 KB
  1// file_encrypt_v2.c
  2// ๊ฐœ์„ ๋œ ํŒŒ์ผ ์•”ํ˜ธํ™” ๋„๊ตฌ (ํ—ค๋” + ํ‚ค ๊ฒ€์ฆ)
  3// ํ•™์Šต ๋ชฉ์ : ๊ตฌ์กฐ์ฒด, ํŒŒ์ผ ํ—ค๋”, ํ•ด์‹œ ํ•จ์ˆ˜, ํ–ฅ์ƒ๋œ ์—๋Ÿฌ ์ฒ˜๋ฆฌ
  4
  5#include <stdio.h>
  6#include <stdlib.h>
  7#include <string.h>
  8#include <stdint.h>
  9
 10// ์ƒ์ˆ˜ ์ •์˜
 11#define MAGIC "XENC"          // ํŒŒ์ผ ์‹๋ณ„์šฉ ๋งค์ง ๋„˜๋ฒ„
 12#define VERSION 1             // ํŒŒ์ผ ํฌ๋งท ๋ฒ„์ „
 13#define BUFFER_SIZE 4096      // 4KB ๋ฒ„ํผ
 14#define HEADER_SIZE 17        // ํ—ค๋” ํฌ๊ธฐ (๋ฐ”์ดํŠธ)
 15
 16/**
 17 * ์•”ํ˜ธํ™” ํŒŒ์ผ ํ—ค๋” ๊ตฌ์กฐ์ฒด
 18 *
 19 * ๊ตฌ์กฐ:
 20 * - magic[4]: "XENC" ๋งค์ง ๋„˜๋ฒ„ (ํŒŒ์ผ ์‹๋ณ„)
 21 * - version: ํŒŒ์ผ ํฌ๋งท ๋ฒ„์ „ (1๋ฐ”์ดํŠธ)
 22 * - key_hash: ํ‚ค์˜ ํ•ด์‹œ๊ฐ’ (4๋ฐ”์ดํŠธ, ํ‚ค ๊ฒ€์ฆ์šฉ)
 23 * - original_size: ์›๋ณธ ํŒŒ์ผ ํฌ๊ธฐ (8๋ฐ”์ดํŠธ)
 24 */
 25typedef struct {
 26    char magic[4];          // ๋งค์ง ๋„˜๋ฒ„: "XENC"
 27    uint8_t version;        // ๋ฒ„์ „: 1
 28    uint32_t key_hash;      // ํ‚ค ํ•ด์‹œ (djb2)
 29    uint64_t original_size; // ์›๋ณธ ํŒŒ์ผ ํฌ๊ธฐ
 30} FileHeader;
 31
 32// ํ•จ์ˆ˜ ์„ ์–ธ
 33void print_usage(const char *name);
 34uint32_t hash_key(const char *key);
 35void xor_buffer(unsigned char *buf, size_t len, const char *key, size_t key_len, size_t *pos);
 36int encrypt_file(const char *input, const char *output, const char *key);
 37int decrypt_file(const char *input, const char *output, const char *key);
 38int show_info(const char *filename);
 39
 40/**
 41 * ๊ฐ„๋‹จํ•œ ํ•ด์‹œ ํ•จ์ˆ˜ (djb2 ์•Œ๊ณ ๋ฆฌ์ฆ˜)
 42 *
 43 * @param key ํ•ด์‹œํ•  ๋ฌธ์ž์—ด
 44 * @return 32๋น„ํŠธ ํ•ด์‹œ๊ฐ’
 45 *
 46 * djb2๋Š” Daniel J. Bernstein์ด ๋งŒ๋“  ๊ฐ„๋‹จํ•˜์ง€๋งŒ ํšจ๊ณผ์ ์ธ ํ•ด์‹œ ํ•จ์ˆ˜
 47 * ์ดˆ๊ธฐ๊ฐ’: 5381
 48 * ๊ณต์‹: hash = hash * 33 + c
 49 */
 50uint32_t hash_key(const char *key) {
 51    uint32_t hash = 5381;
 52    int c;
 53
 54    while ((c = *key++)) {
 55        // hash * 33 + c = (hash << 5) + hash + c
 56        hash = ((hash << 5) + hash) + c;
 57    }
 58
 59    return hash;
 60}
 61
 62/**
 63 * ์‚ฌ์šฉ๋ฒ• ์ถœ๋ ฅ
 64 */
 65void print_usage(const char *name) {
 66    printf("๊ฐœ์„ ๋œ ํŒŒ์ผ ์•”ํ˜ธํ™” ๋„๊ตฌ v2\n\n");
 67    printf("์‚ฌ์šฉ๋ฒ•:\n");
 68    printf("  %s encrypt <์ž…๋ ฅํŒŒ์ผ> <์ถœ๋ ฅํŒŒ์ผ> <๋น„๋ฐ€๋ฒˆํ˜ธ>\n", name);
 69    printf("  %s decrypt <์ž…๋ ฅํŒŒ์ผ> <์ถœ๋ ฅํŒŒ์ผ> <๋น„๋ฐ€๋ฒˆํ˜ธ>\n", name);
 70    printf("  %s info <์•”ํ˜ธํ™”ํŒŒ์ผ>\n", name);
 71    printf("\n์˜ˆ์ œ:\n");
 72    printf("  %s encrypt secret.txt secret.enc mypassword\n", name);
 73    printf("  %s decrypt secret.enc decrypted.txt mypassword\n", name);
 74    printf("  %s info secret.enc\n", name);
 75}
 76
 77/**
 78 * ๋ฒ„ํผ๋ฅผ XOR ์•”ํ˜ธํ™”/๋ณตํ˜ธํ™” (ํ‚ค ์œ„์น˜ ์ถ”์ )
 79 *
 80 * @param buf ์ฒ˜๋ฆฌํ•  ๋ฒ„ํผ
 81 * @param len ๋ฒ„ํผ ๊ธธ์ด
 82 * @param key ์•”ํ˜ธํ™” ํ‚ค
 83 * @param key_len ํ‚ค ๊ธธ์ด
 84 * @param pos ํ‚ค์˜ ํ˜„์žฌ ์œ„์น˜ (ํฌ์ธํ„ฐ, ์ƒํƒœ ์œ ์ง€)
 85 *
 86 * pos ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์—ฌ๋Ÿฌ ๋ฒ„ํผ์— ๊ฑธ์ณ ํ‚ค ์œ„์น˜๋ฅผ ์—ฐ์†์ ์œผ๋กœ ์ถ”์ 
 87 * ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํŒŒ์ผ์„ ์—ฌ๋Ÿฌ ๋ธ”๋ก์œผ๋กœ ๋‚˜๋ˆ  ์ฝ์–ด๋„ ํ‚ค ํŒจํ„ด์ด ์ผ๊ด€๋จ
 88 */
 89void xor_buffer(unsigned char *buf, size_t len, const char *key, size_t key_len, size_t *pos) {
 90    for (size_t i = 0; i < len; i++) {
 91        buf[i] ^= key[*pos % key_len];
 92        (*pos)++;  // ํ‚ค ์œ„์น˜ ์ฆ๊ฐ€
 93    }
 94}
 95
 96/**
 97 * ํŒŒ์ผ ์•”ํ˜ธํ™” (ํ—ค๋” ํฌํ•จ)
 98 *
 99 * @param input ์ž…๋ ฅ ํŒŒ์ผ ๊ฒฝ๋กœ
100 * @param output ์ถœ๋ ฅ ํŒŒ์ผ ๊ฒฝ๋กœ
101 * @param key ์•”ํ˜ธํ™” ํ‚ค
102 * @return ์„ฑ๊ณต ์‹œ 0, ์‹คํŒจ ์‹œ 1
103 */
104int encrypt_file(const char *input, const char *output, const char *key) {
105    // ์ž…๋ ฅ ํŒŒ์ผ ์—ด๊ธฐ
106    FILE *fin = fopen(input, "rb");
107    if (!fin) {
108        perror("์ž…๋ ฅ ํŒŒ์ผ ์—ด๊ธฐ ์‹คํŒจ");
109        return 1;
110    }
111
112    // ์›๋ณธ ํŒŒ์ผ ํฌ๊ธฐ ํ™•์ธ
113    fseek(fin, 0, SEEK_END);
114    uint64_t file_size = ftell(fin);
115    fseek(fin, 0, SEEK_SET);
116
117    // ์ถœ๋ ฅ ํŒŒ์ผ ์—ด๊ธฐ
118    FILE *fout = fopen(output, "wb");
119    if (!fout) {
120        perror("์ถœ๋ ฅ ํŒŒ์ผ ์—ด๊ธฐ ์‹คํŒจ");
121        fclose(fin);
122        return 1;
123    }
124
125    // ํ—ค๋” ๊ตฌ์กฐ์ฒด ์ดˆ๊ธฐํ™”
126    FileHeader header;
127    memcpy(header.magic, MAGIC, 4);     // "XENC" ๋ณต์‚ฌ
128    header.version = VERSION;            // ๋ฒ„์ „ 1
129    header.key_hash = hash_key(key);     // ํ‚ค์˜ ํ•ด์‹œ๊ฐ’ ์ €์žฅ
130    header.original_size = file_size;    // ์›๋ณธ ํฌ๊ธฐ ์ €์žฅ
131
132    // ํ—ค๋”๋ฅผ ํŒŒ์ผ์— ๊ธฐ๋ก
133    fwrite(&header, sizeof(FileHeader), 1, fout);
134
135    // ๋ฐ์ดํ„ฐ ์•”ํ˜ธํ™”
136    unsigned char buffer[BUFFER_SIZE];
137    size_t bytes_read;
138    size_t key_len = strlen(key);
139    size_t key_pos = 0;  // ํ‚ค ์œ„์น˜ ์ถ”์ 
140
141    printf("์•”ํ˜ธํ™” ์ค‘...\n");
142    while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, fin)) > 0) {
143        xor_buffer(buffer, bytes_read, key, key_len, &key_pos);
144        fwrite(buffer, 1, bytes_read, fout);
145
146        // ๊ฐ„๋‹จํ•œ ์ง„ํ–‰๋ฅ  ํ‘œ์‹œ
147        printf(".");
148        fflush(stdout);
149    }
150    printf("\n");
151
152    fclose(fin);
153    fclose(fout);
154
155    printf("์•”ํ˜ธํ™” ์™„๋ฃŒ: %s -> %s\n", input, output);
156    printf("์›๋ณธ ํฌ๊ธฐ: %llu ๋ฐ”์ดํŠธ\n", (unsigned long long)file_size);
157    printf("ํ‚ค ํ•ด์‹œ: 0x%08X\n", header.key_hash);
158
159    return 0;
160}
161
162/**
163 * ํŒŒ์ผ ๋ณตํ˜ธํ™” (ํ—ค๋” ๊ฒ€์ฆ ํฌํ•จ)
164 *
165 * @param input ์ž…๋ ฅ ํŒŒ์ผ ๊ฒฝ๋กœ (์•”ํ˜ธํ™”๋œ ํŒŒ์ผ)
166 * @param output ์ถœ๋ ฅ ํŒŒ์ผ ๊ฒฝ๋กœ (๋ณตํ˜ธํ™”๋œ ํŒŒ์ผ)
167 * @param key ๋ณตํ˜ธํ™” ํ‚ค
168 * @return ์„ฑ๊ณต ์‹œ 0, ์‹คํŒจ ์‹œ 1
169 */
170int decrypt_file(const char *input, const char *output, const char *key) {
171    // ์•”ํ˜ธํ™”๋œ ํŒŒ์ผ ์—ด๊ธฐ
172    FILE *fin = fopen(input, "rb");
173    if (!fin) {
174        perror("์ž…๋ ฅ ํŒŒ์ผ ์—ด๊ธฐ ์‹คํŒจ");
175        return 1;
176    }
177
178    // ํ—ค๋” ์ฝ๊ธฐ
179    FileHeader header;
180    if (fread(&header, sizeof(FileHeader), 1, fin) != 1) {
181        fprintf(stderr, "์˜ค๋ฅ˜: ์ž˜๋ชป๋œ ์•”ํ˜ธํ™” ํŒŒ์ผ (ํ—ค๋” ์ฝ๊ธฐ ์‹คํŒจ)\n");
182        fclose(fin);
183        return 1;
184    }
185
186    // ๋งค์ง ๋„˜๋ฒ„ ํ™•์ธ (ํŒŒ์ผ์ด XENC ํ˜•์‹์ธ์ง€ ๊ฒ€์ฆ)
187    if (memcmp(header.magic, MAGIC, 4) != 0) {
188        fprintf(stderr, "์˜ค๋ฅ˜: ์œ ํšจํ•œ ์•”ํ˜ธํ™” ํŒŒ์ผ์ด ์•„๋‹™๋‹ˆ๋‹ค (๋งค์ง ๋„˜๋ฒ„ ๋ถˆ์ผ์น˜)\n");
189        fprintf(stderr, "๊ธฐ๋Œ€๊ฐ’: %.4s, ์‹ค์ œ๊ฐ’: %.4s\n", MAGIC, header.magic);
190        fclose(fin);
191        return 1;
192    }
193
194    // ๋ฒ„์ „ ํ™•์ธ
195    if (header.version != VERSION) {
196        fprintf(stderr, "๊ฒฝ๊ณ : ํŒŒ์ผ ๋ฒ„์ „์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค (๊ธฐ๋Œ€: %d, ์‹ค์ œ: %d)\n",
197                VERSION, header.version);
198    }
199
200    // ํ‚ค ๊ฒ€์ฆ (ํ•ด์‹œ ๋น„๊ต)
201    uint32_t input_key_hash = hash_key(key);
202    if (header.key_hash != input_key_hash) {
203        fprintf(stderr, "์˜ค๋ฅ˜: ์ž˜๋ชป๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ\n");
204        fprintf(stderr, "๊ธฐ๋Œ€ ํ•ด์‹œ: 0x%08X, ์ž…๋ ฅ ํ•ด์‹œ: 0x%08X\n",
205                header.key_hash, input_key_hash);
206        fclose(fin);
207        return 1;
208    }
209
210    // ์ถœ๋ ฅ ํŒŒ์ผ ์—ด๊ธฐ
211    FILE *fout = fopen(output, "wb");
212    if (!fout) {
213        perror("์ถœ๋ ฅ ํŒŒ์ผ ์—ด๊ธฐ ์‹คํŒจ");
214        fclose(fin);
215        return 1;
216    }
217
218    // ๋ฐ์ดํ„ฐ ๋ณตํ˜ธํ™”
219    unsigned char buffer[BUFFER_SIZE];
220    size_t bytes_read;
221    size_t key_len = strlen(key);
222    size_t key_pos = 0;  // ํ‚ค ์œ„์น˜ ์ถ”์ 
223
224    printf("๋ณตํ˜ธํ™” ์ค‘...\n");
225    while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, fin)) > 0) {
226        xor_buffer(buffer, bytes_read, key, key_len, &key_pos);
227        fwrite(buffer, 1, bytes_read, fout);
228
229        // ์ง„ํ–‰๋ฅ  ํ‘œ์‹œ
230        printf(".");
231        fflush(stdout);
232    }
233    printf("\n");
234
235    fclose(fin);
236    fclose(fout);
237
238    printf("๋ณตํ˜ธํ™” ์™„๋ฃŒ: %s -> %s\n", input, output);
239    printf("์›๋ณธ ํฌ๊ธฐ: %llu ๋ฐ”์ดํŠธ\n", (unsigned long long)header.original_size);
240
241    return 0;
242}
243
244/**
245 * ์•”ํ˜ธํ™” ํŒŒ์ผ ์ •๋ณด ํ‘œ์‹œ
246 *
247 * @param filename ์•”ํ˜ธํ™” ํŒŒ์ผ ๊ฒฝ๋กœ
248 * @return ์„ฑ๊ณต ์‹œ 0, ์‹คํŒจ ์‹œ 1
249 */
250int show_info(const char *filename) {
251    FILE *fp = fopen(filename, "rb");
252    if (!fp) {
253        perror("ํŒŒ์ผ ์—ด๊ธฐ ์‹คํŒจ");
254        return 1;
255    }
256
257    FileHeader header;
258    if (fread(&header, sizeof(FileHeader), 1, fp) != 1) {
259        fprintf(stderr, "์˜ค๋ฅ˜: ํ—ค๋”๋ฅผ ์ฝ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค\n");
260        fclose(fp);
261        return 1;
262    }
263
264    // ํŒŒ์ผ ์ „์ฒด ํฌ๊ธฐ ํ™•์ธ
265    fseek(fp, 0, SEEK_END);
266    long total_size = ftell(fp);
267    fclose(fp);
268
269    // ๋งค์ง ๋„˜๋ฒ„ ํ™•์ธ
270    if (memcmp(header.magic, MAGIC, 4) != 0) {
271        printf("์•”ํ˜ธํ™” ํŒŒ์ผ์ด ์•„๋‹™๋‹ˆ๋‹ค (XENC ๋งค์ง ๋„˜๋ฒ„ ์—†์Œ)\n");
272        return 1;
273    }
274
275    // ์ •๋ณด ์ถœ๋ ฅ
276    printf("=== ์•”ํ˜ธํ™” ํŒŒ์ผ ์ •๋ณด ===\n");
277    printf("๋งค์ง ๋„˜๋ฒ„: %.4s\n", header.magic);
278    printf("๋ฒ„์ „: %d\n", header.version);
279    printf("ํ‚ค ํ•ด์‹œ: 0x%08X\n", header.key_hash);
280    printf("์›๋ณธ ํฌ๊ธฐ: %llu ๋ฐ”์ดํŠธ\n", (unsigned long long)header.original_size);
281    printf("ํŒŒ์ผ ํฌ๊ธฐ: %ld ๋ฐ”์ดํŠธ\n", total_size);
282    printf("ํ—ค๋” ํฌ๊ธฐ: %lu ๋ฐ”์ดํŠธ\n", sizeof(FileHeader));
283    printf("์•”ํ˜ธํ™” ๋ฐ์ดํ„ฐ: %ld ๋ฐ”์ดํŠธ\n", total_size - (long)sizeof(FileHeader));
284
285    return 0;
286}
287
288/**
289 * ๋ฉ”์ธ ํ•จ์ˆ˜
290 */
291int main(int argc, char *argv[]) {
292    if (argc < 2) {
293        print_usage(argv[0]);
294        return 1;
295    }
296
297    // ๋ช…๋ น ๋ถ„๊ธฐ
298    if (strcmp(argv[1], "encrypt") == 0) {
299        if (argc < 5) {
300            print_usage(argv[0]);
301            return 1;
302        }
303        return encrypt_file(argv[2], argv[3], argv[4]);
304    }
305    else if (strcmp(argv[1], "decrypt") == 0) {
306        if (argc < 5) {
307            print_usage(argv[0]);
308            return 1;
309        }
310        return decrypt_file(argv[2], argv[3], argv[4]);
311    }
312    else if (strcmp(argv[1], "info") == 0) {
313        if (argc < 3) {
314            print_usage(argv[0]);
315            return 1;
316        }
317        return show_info(argv[2]);
318    }
319    else {
320        fprintf(stderr, "์˜ค๋ฅ˜: ์•Œ ์ˆ˜ ์—†๋Š” ๋ช…๋ น '%s'\n", argv[1]);
321        print_usage(argv[0]);
322        return 1;
323    }
324
325    return 0;
326}