2011년경에 썼던 글로 아래의 코드는 지금은 바뀌었을 가능성이 있음..
AES 암호화 알고리즘을 사용하여 데이터를 암호화와 해제를 하는 코드를 필요하여 잠시 만들어봄.
AES 알고리즘은 민감하지만 비밀로 분류되지는 않은 자료들에 대해 보안을 유지하기 위해 미국 정부기관들이
사용하는 암호화 알고리즘이며, 그에 따라 민간 부문의 상업 거래용으로서 사실상의 암호화 표준으로 자리 잡음.
최소 128 비트나 192 비트 또는 256 비트 크기의 키를 지원하는 128 비트 크기의 블록 암호화를 사용한
대칭형 (암호화나 복호화를 하는데 동일한 키가 사용되는) 알고리즘.
여기서는 libgcrypt 라이브러리에 제공하는 AES 알고리즘 기능을 사용하였으며 컴파일러는 MinGW를 사용함.
암호화
#include <stdio.h>
#include <stdlib.h>
#include <gcrypt.h>
#include <sys/stat.h>
static void *
read_file (const char *fname, size_t *r_length)
{
FILE *fp;
struct stat st;
char *buf;
size_t buflen;
fp = fopen (fname, "rb");
if (!fp)
{
printf ("can't open `%s': %s\n", fname, strerror (errno));
return NULL;
}
if (fstat (fileno(fp), &st))
{
printf ("can't stat `%s': %s\n", fname, strerror (errno));
fclose (fp);
return NULL;
}
buflen = st.st_size;
buf = gcry_xmalloc (buflen+1);
if (fread (buf, buflen, 1, fp) != 1)
{
printf ("error reading `%s': %s\n", fname, strerror (errno));
fclose (fp);
gcry_free (buf);
return NULL;
}
fclose (fp);
if (r_length)
*r_length = buflen;
return buf;
}
int main()
{
const int BLOCKSIZE = 16;
//암호화할 파일을 버퍼로 불러옴.
size_t file_length;
unsigned char *plaintext = read_file("rate_CF4.xml", &file_length);
//Initialize
printf("Initializing... Version: %s\n", gcry_check_version(NULL));
//Symmetric key generation (128 bit)
printf("Generating symmetric key (128 bit)...\n");
//Allocate a byte-array for holding the key
unsigned char* key = (unsigned char*) malloc(BLOCKSIZE*sizeof(char));
//Use secure random number generation (아래를 사용하면 랜덤키를 생성)
//gcry_randomize(key, BLOCKSIZE, GCRY_STRONG_RANDOM);
//위의 랜덤키대신 키를 지정 (이 키가 복호화시에도 쓰이며, 키는 128비트인 16 character로 지정함.)
sprintf(key, "this_is_base_key");
//Print the key
printf("Key is: ");
int i;
for(i=0;i<BLOCKSIZE;i++)
printf("%X ", key[i]);
printf("\n");
//Symmetric encryption with AES
gcry_error_t err;
gcry_cipher_hd_t hd;
//Initialization vector
unsigned char* iv = "1234567812345678";
//Allocate memory for ciphertext
unsigned char* ciphertext = (unsigned char*) malloc(file_length*sizeof(char));
//Open cipher
printf("Opening AES cipher...\n");
err = gcry_cipher_open(&hd, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CFB, NULL);
if(err)
{
printf("Failed opening AES cipher: %s\n", gpg_strerror(err));
return;
}
//Set key for cipher
printf("Setting the key...\n");
err = gcry_cipher_setkey(hd, key, BLOCKSIZE);
if(err)
{
printf("Failed setting the key: %s\n", gpg_strerror(err));
return;
}
//Set iv
printf("Setting the initialization vector %s...\n", iv);
err = gcry_cipher_setiv(hd, iv, BLOCKSIZE);
if(err)
{
printf("Failed setting the initialization vector: %s\n", gpg_strerror(err));
return;
}
//Encrypt
printf("Encrypting plaintext: %s...\n", plaintext);
err = gcry_cipher_encrypt(hd, ciphertext, file_length, plaintext, file_length);
if(err)
{
printf("Encryption failed: %s\n", gpg_strerror(err));
return;
}
//Write
FILE *fp = fopen("encrypted.xml", "wb");
fwrite(ciphertext, sizeof(char), file_length, fp);
fclose(fp);
printf("Resulting ciphertext (hex): ");
for(i=0;i<file_length;i++)
printf("%X ", ciphertext[i]);
printf("\n");
//Cleanup
gcry_cipher_close(hd);
free(key);
free(ciphertext);
return 0;
}
복호화
#include <stdio.h>
#include <stdlib.h>
#include <gcrypt.h>
#include <sys/stat.h>
static void *
read_file (const char *fname, size_t *r_length)
{
FILE *fp;
struct stat st;
char *buf;
size_t buflen;
fp = fopen (fname, "rb");
if (!fp)
{
printf ("can't open `%s': %s\n", fname, strerror (errno));
return NULL;
}
if (fstat (fileno(fp), &st))
{
printf ("can't stat `%s': %s\n", fname, strerror (errno));
fclose (fp);
return NULL;
}
buflen = st.st_size;
buf = gcry_xmalloc (buflen+1);
if (fread (buf, buflen, 1, fp) != 1)
{
printf ("error reading `%s': %s\n", fname, strerror (errno));
fclose (fp);
gcry_free (buf);
return NULL;
}
fclose (fp);
if (r_length)
*r_length = buflen;
return buf;
}
int main()
{
const int BLOCKSIZE = 16;
//Initialize
printf("Initializing... Version: %s\n", gcry_check_version(NULL));
//Symmetric key generation (128 bit)
printf("Generating symmetric key (128 bit)...\n");
//Allocate a byte-array for holding the key
unsigned char* key = (unsigned char*) malloc(BLOCKSIZE*sizeof(char));
//Use secure random number generation
//gcry_randomize(key, BLOCKSIZE, GCRY_STRONG_RANDOM);
sprintf(key, "this_is_base_key");
//Print the key
printf("Key is: ");
int i;
for(i=0;i<BLOCKSIZE;i++)
printf("%X ", key[i]);
printf("\n");
//Symmetric encryption with AES
gcry_error_t err;
gcry_cipher_hd_t hd;
//Initialization vector
unsigned char* iv = "1234567812345678";
//Allocate memory for ciphertext
//unsigned char* ciphertext = (unsigned char*) malloc(file_length*sizeof(char));
size_t file_length;
unsigned char *ciphertext = read_file("encrypted.xml", &file_length);
//Open cipher
printf("Opening AES cipher...\n");
err = gcry_cipher_open(&hd, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CFB, NULL);
if(err)
{
printf("Failed opening AES cipher: %s\n", gpg_strerror(err));
return;
}
//Set key for cipher
printf("Setting the key...\n");
err = gcry_cipher_setkey(hd, key, BLOCKSIZE);
if(err)
{
printf("Failed setting the key: %s\n", gpg_strerror(err));
return;
}
//Set iv
printf("Setting the initialization vector %s...\n", iv);
err = gcry_cipher_setiv(hd, iv, BLOCKSIZE);
if(err)
{
printf("Failed setting the initialization vector: %s\n", gpg_strerror(err));
return;
}
printf("Decrypting...\n");
//Memory for storing the decryption result
unsigned char* decryptedtext = (unsigned char*) malloc(file_length*sizeof(char));
err = gcry_cipher_decrypt(hd, decryptedtext, file_length, ciphertext, file_length);
if(err)
{
//printf("Decryption failed: %s\n", gpg_strerror(err));
return;
}
//Write
FILE *fp = fopen("decrypted.xml", "w");
fwrite(decryptedtext, sizeof(char), file_length, fp);
fclose(fp);
printf("Decrypted text (%d bytes): %s\n", file_length, decryptedtext);
//Cleanup
gcry_cipher_close(hd);
free(key);
free(ciphertext);
free(decryptedtext);
getch();
return 0;
}
컴파일 방법
all:
gcc -o encrypt.exe encrypt.c `libgcrypt-config --cflags --libs`
gcc -o decrypt.exe decrypt.c `libgcrypt-config --cflags --libs`
참고로 위의 암호화 코드를 실행하면 encrypted.xml 파일이 만들어지는데 아래와 같이 알 수 없는 코드로 변경됨.
'블로그 (Blog) > 개발로그 (Devlogs)' 카테고리의 다른 글
디바이스 드라이버에서 atof 함수 구현 (0) | 2025.02.18 |
---|---|
MinGW 컴파일러에서 멀티코어 사용하기 (0) | 2025.02.18 |
struct의 좋은 예(?) (0) | 2025.02.18 |
READ_REGISTER, WRITE_REGISTER… (0) | 2025.02.18 |
유용한 define문 (0) | 2025.02.18 |