[ 암호화 ] AES crypto cbc 모드 C 샘플 by openssl 용-ILE/LNAG-C/C++2013. 6. 4. 14:32
http://suite.tistory.com 2013.06 fs
openssl 라이브러리 함수 이용하여 aes cbc 함수 샘플 작성해봄
1. openssl 최신버전 2013.06 기준 다운로드
$>wget http://www.openssl.org/source/openssl-1.0.1e.tar.gz
2. 압축 풀기
$>tar fxz openssl-1.0.1e.tar.gz
3. libcrypto.a 생성
$>cd openssl-1.0.1e;make
-> $> ls 해서 libcrypto.a 파일 확인
4. openssl-1.0.1e/apps/speed.c 참고해서
build : $>gcc fs_aes_cbc.c libcrypto.a
static const unsigned char key32[32]= {0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0, 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12, 0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34, 0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,0x56};
#define BLOCK_SIZE 16 #define FREAD_COUNT 4096 #define KEY_BIT 256 #define IV_SIZE 16 #define RW_SIZE 1 #define SUCC 0 #define FAIL -1 AES_KEY aes_ks3; unsigned char iv[IV_SIZE]; int fs_encrypt_aes(char *in_file,char *out_file) { int i=0; int len=0; int padding_len=0; char buf[FREAD_COUNT+BLOCK_SIZE]; FILE *fp=fopen(in_file,"rb"); if( fp == NULL ){ fprintf(stderr,"[ERROR] %d can not fopen('%s')\n",__LINE__,in_file); return FAIL; } FILE *wfp=fopen(out_file,"wb"); if( wfp == NULL ){ fprintf(stderr,"[ERROR] %d can not fopen('%s')\n",__LINE__,out_file); return FAIL; } memset(iv,0,sizeof(iv)); // init iv AES_set_encrypt_key(key32 ,KEY_BIT ,&aes_ks3); while( len = fread( buf ,RW_SIZE ,FREAD_COUNT, fp) ){ if( FREAD_COUNT != len ){ break; } AES_cbc_encrypt(buf ,buf ,len ,&aes_ks3 ,iv ,AES_ENCRYPT); fwrite(buf ,RW_SIZE ,len ,wfp); } // padding : pkcs5? pkcs7?? http://wiki.dgoon.net/doku.php?id=ssl:pkcs_5 padding_len=BLOCK_SIZE - len % BLOCK_SIZE; printf("enc padding len:%d\n",padding_len); memset(buf+len, padding_len, padding_len); /** for(i=len; i < len+padding_len ;i++){ buf[i]=padding_len; } **/ AES_cbc_encrypt(buf ,buf ,len+padding_len ,&aes_ks3, iv,AES_ENCRYPT); fwrite(buf ,RW_SIZE ,len+padding_len ,wfp); fclose(wfp); fclose(fp); return SUCC; } int fs_decrypt_aes(char *in_file,char *out_file) { char buf[FREAD_COUNT+BLOCK_SIZE]; int len=0; int total_size=0; int save_len=0; int w_len=0; FILE *fp=fopen(in_file,"rb"); if( fp == NULL ){ fprintf(stderr,"[ERROR] %d can not fopen('%s')\n",__LINE__,in_file); return FAIL; } FILE *wfp=fopen(out_file,"wb"); if( wfp == NULL ){ fprintf(stderr,"[ERROR] %d can not fopen('%s')\n",__LINE__,out_file); return FAIL; } memset(iv,0,sizeof(iv)); // the same iv AES_set_decrypt_key(key32 ,KEY_BIT ,&aes_ks3); fseek(fp ,0 ,SEEK_END); total_size=ftell(fp); fseek(fp ,0 ,SEEK_SET); printf("total_size %d\n",total_size); while( len = fread( buf ,RW_SIZE ,FREAD_COUNT ,fp) ){ if( FREAD_COUNT == 0 ){ break; } save_len+=len; w_len=len; AES_cbc_encrypt(buf ,buf ,len ,&aes_ks3 ,iv ,AES_DECRYPT); if( save_len == total_size ){ // check last block w_len=len - buf[len-1]; printf("dec padding size %d\n" ,buf[len-1]); } fwrite(buf ,RW_SIZE ,w_len ,wfp); } fclose(wfp); fclose(fp); return SUCC; } //copyleft @http://suite.tistory.com fs int main(int argc, char *args[]) { if( argc != 2 ){ printf("[Usage] %s fs_src_file\n",args[0]); return FAIL; } if( fs_encrypt_aes(args[1],"fs_in.file") == SUCC){ fs_decrypt_aes("fs_in.file","fs_out.file"); printf("result:[fs_out.file]\n"); } return 0; }
* 실행 결과
$ vi fs_aes_cbc.c $ make gcc fs_aes_cbc.c libcrypto.a $ ./a.out fs_aes_cbc.c result:[out.file] $ ls -ltr 합계 11512 -rw-rw-r--. 1 ir ir 3914268 2013-05-31 17:03 libcrypto.a -rw-rw-r--. 1 ir ir 36 2013-06-04 15:10 Makefile -rw-rw-r--. 1 i ir 2979 2013-06-04 15:10 fs_aes_cbc.c -rwxrwxr-x. 1 ir i 23698 2013-06-04 16:21 a.out -rw-rw-r--. 1 i ir 2992 2013-06-04 16:21 fs_in.file -rw-rw-r--. 1 irtu irt 2979 2013-06-04 16:21 fs_out.file
실제 업무에서는 C++ 기반이면 class화 사용이 BEST!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 참고 링크 : http://misc-file.googlecode.com/svn/vm/aes_cbc_encrypt.cpp
* EVP? : openssl 암호화 관련 검색을 계속 해보면 EVP 관련 함수로 암호화 함수가 있다.
EVP 무슨약자인지는 찾지 못했고 "하이레벨 함수들" : http://www.openssl.org/docs/crypto/evp.html
fs/openssl-1.0.1e/test/evp*.c 보면
EVP_CIPHER_CTX_init() , EVP_EncryptUpdate() , EVP_EncryptFinal() 이용해서 암호화 알고리즘을 적용 하는 예제가 있음
'용-ILE > LNAG-C/C++' 카테고리의 다른 글
[ 암호화 ] AES crypto ctr 모드 C 샘플 by openssl (0) | 2013.07.10 |
---|---|
[ 암호화 ] cipher 학습해 보면 이거 저거 용어 (대칭형,공개키,des,aes,cbc,iv..) 작성중... (0) | 2013.06.03 |
[gdb] shared-libraries so 공유 라이브러리 디버깅 attach 활용 (0) | 2011.10.27 |
[ 도미노 / 노츠 6.5.6 ] C API 텍스트 추출 샘플 (0) | 2010.01.27 |
[C - 당연한거 2] strcpy ( str , "" ) 하고 memset ( str , '\0',sizeof(SEC_TMP) ) (1) | 2008.08.26 |