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