블로그 이미지
핑크대지

태그목록

공지사항

최근에 올라온 글

최근에 달린 댓글

글 보관함

calendar

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

[OpenSSL 프로그래밍] AES 암호화 (EVP)

2009. 3. 10. 10:14 | Posted by 핑크대지

1. AES 암호화 알고리즘
- 기본적으로 암호화란 평문(plain text)을 암호문(cipher text)으로 바꾸는 작업을 말한다.
- AES 란 Advanced Encryption Standard의 약자로 가장 많이 쓰이는 블럭 암호화 알고리즘으로 128 bit/192 bit/256 bit 의 대칭키를 이용하여 데이터를 암호화 한다.

2. OpenSSL 라이브러리 제공 (AES 암호화 방식)
  1) EVP 라이브러리
  2) AES 라이브러리

OpenSSL에서는 두 가지 방식의 AES 암복호화 라이브러리를 제공한다. 기본 AES 암호화 API 이외에 EVP 라이브러리가 바로 그것이다. 오늘은 두 방식 중 EVP API를 이용한 AES 암호화 프로그래밍에 대해서 알아 보도록 하자.

3. 암호화 과정
- 모든 암호화 라이브러리는 init, update, final 과정을 거친다.
- init: 암호화 관련 정보를 설정한다. (암호화 방식, 키 길이, 비밀 번호 등)
- update: 설정한 암호화 방식으로 블럭을 분할해 암호화를 수행한다.
- final: 입력한 plain text의 크기가 블럭의 배수가 아닐 경우 데이터 끝에 여분의 데이터 바이트가 남게 되는 해당 바이트를 패딩하여 처리가능한 크기의 블럭으로 만든 다음 암호화를 수행한다.


4. 암호화 프로그래밍
- 일단 코드를 보자. 아래는 입력 받은 plain text를 복호화 키를 이용하여 cipher text로 변환하는 함수이다.

#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/ssl.h>

/* AES Encrypt Process */
int encrypt_block(unsigned char* cipherText, unsigned char* plainText, unsigned int plainTextLen, unsigned char* key)
{
    EVP_CIPHER_CTX ctx;
    int addLen=0, orgLen=0;
    unsigned long err=0;
   
    ERR_load_crypto_strings();
    EVP_CIPHER_CTX_init(&ctx);
    if (EVP_EncryptInit(&ctx, EVP_aes_128_ecb(), key, NULL) != 1) {
        err = ERR_get_error();
        printf("ERR: EVP_EncryptInit() - %s\n", ERR_error_string (err, NULL));
        return -1;
     }
    if (EVP_EncryptUpdate(&ctx, cipherText, &orgLen, plainText, plainTextLen) != 1) {
        err = ERR_get_error();
        printf("ERR: EVP_EncryptUpdate() - %s\n", ERR_error_string (err, NULL));
   
        return -1;
    }
 
    if (EVP_EncryptFinal(&ctx, cipherText+orgLen, &addLen) != 1) {
        err = ERR_get_error();
        printf("ERR: EVP_EncryptFinal() - %s\n", ERR_error_string (err, NULL));
        return -1;
    }
    EVP_CIPHER_CTX_cleanup(&ctx);
    ERR_free_strings();
    return addLen + orgLen;
}

- EVP 라이브러리를 사용하기 전에는 먼저 context를 설정해야 하는데.. context 구조체에는 암호화에 관련된 정보가 기록된다. EVP_CIPHER_CTX_init()로 초기화를 수행하고, EVP_CIPHER_CTX_cleanup()을 통해 해제를 수행한다.
- 블럭 암호화 알고리즘에는 ECB, CBC 등의 모드가 사용되는데 해당 함수에서는 ECB 방식을 사용한다. (모드에 대한 설명은 향후에 시간이 나면.. ^^;;)

- 아래는 AES로 암호화된 cipher text를 plain text로 복호화하는 함수이다.

#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/ssl.h>

/* AES Decrypt Process */
int decrypt_block(unsigned char* plainText, unsigned char* cipherText, unsigned int cipherTextLen, unsigned char* key)
{
    EVP_CIPHER_CTX ctx;
    unsigned long err=0;
    int toLen=0, outLen=0;
    int ret=0;
 
    ERR_load_crypto_strings();
    EVP_CIPHER_CTX_init(&ctx);
 
    if (EVP_DecryptInit(&ctx, EVP_aes_128_ecb(), key, NULL) != 1) {
        err = ERR_get_error();
        printf("ERR: EVP_DecryptInit() - %s\n", ERR_error_string (err, NULL));
        return -1;
    }
    if (EVP_DecryptUpdate(&ctx, plainText, &toLen, cipherText, cipherTextLen) != 1) {
        err = ERR_get_error();  
        printf("ERR: EVP_DecryptUpdate() - %s\n", ERR_error_string (err, NULL));
   
        return -1;
    }
 
    if (EVP_DecryptFinal(&ctx, &plainText[cipherTextLen], &outLen) != 1) {
        err = ERR_get_error();
        printf("ERR: EVP_DecryptFinal() - %s\n", ERR_error_string (err, NULL));
 
        return -1;
    }
 
    EVP_CIPHER_CTX_cleanup(&ctx);
    ERR_free_strings();
 
    return toLen+outLen;
}

2009.02.13

2009. 2. 13. 13:36 | Posted by 핑크대지
13일...
막상 날짜를 적고보니 오늘이 금요일이다.
비도 추적추적 내리는...
꾸물하고 스산한 날이다.

일주일이 어떻게 지나간 지도 모르게
매일 피곤에 쩔어있었던 것 같은데. 금요일이라.
상태는 오늘도 마찬가지이긴 하다.
그러나, 일찍 퇴근할까 야근을 할까 아직도 고민중이다.

이제 딱 일주일 남았다.
그러면, 그가 돌아온다. 볼 수 있다.
달력에 꼬박꼬박 표시하던 X자가 절반을 넘어섰다.
기쁘다. ㅎㅎㅎ

음...
이번 주말은 무얼 하면 좋을까...?