본문으로 바로가기

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 파일이 만들어지는데 아래와 같이 알 수 없는 코드로 변경됨.