CPP aes128 str mode Encryption Decryption Using openssl library
Programming/C,CPP,CS 2016. 9. 5. 13:41CPP aes128 cbc mode Encryption Decryption
AES
Encryption Block :
128 비트
192 비트
256 비트
Mode :
1. ECB ( Electric Code Book )
http://jo.centis1504.net/wp-content/uploads/2010/11/Encryption-ECB_MODE.swf
2. CBC ( Cipher Block Chaining )
http://jo.centis1504.net/wp-content/uploads/2010/11/Encryption-CBC_MODE.swf
3. OFB ( Output Feed Back )
http://jo.centis1504.net/wp-content/uploads/2010/11/Encryption-OFB_MODE.swf
4. CFB ( Cipher Feed Back )
5. CTR ( CounTeR )
모드별 설명은
관련 자료 참고 : http://www.parkjonghyuk.net/lecture/modernCrypto/lecturenote/chap04.pdf
구현에서는 CTR 모드로 구현하였다.
개발 환경 : Windows 7 64bit, VS 2013
최신버전으로 직접 빌드하시려면 아래의 링크를 참조하시기 바랍니다.
귀찮으신 분은 빌드된 버전을 사용합시다.
"openssl-1.0.1f_vc_no-idea no-mdc2 no-rc5_build.zip" 는 no-idea no-mdc2 no-rc5 로 빌드된, 특허문제가 해결 된 바이너리입니다.
openssl-1.0.1f_vc_no-idea no-mdc2 no-rc5_build.zip압축 해제 후 파일을 프로젝트 폴더로 이동
프로젝트속성 > VC++ 디렉터리 > 디렉터리 설정 (포함 디렉터리, 라이브러리 디렉터리)
별도의 클래스를 만들어 사용 하였습니다.
#pragma once #include#include #include #include struct ctr_state { unsigned char ivec[AES_BLOCK_SIZE]; unsigned int num; unsigned char ecount[AES_BLOCK_SIZE]; }; class CAESCTR { public: AES_KEY key; int BYTES_SIZE = 1024; int KEY_SIZE = 128; unsigned char ckey[32]; unsigned char iv[8]; int init_ctr(struct ctr_state *state, const unsigned char iv[8]); void encrypt(unsigned char *indata, unsigned char *outdata, int bytes_read); void encrypt(CString& indata, CString& outdata, int bytes_read); CAESCTR(); CAESCTR::CAESCTR(unsigned char* iv, unsigned char* ckey); ~CAESCTR(); };
#include "stdafx.h"
#include "AESCTR.h"
int CAESCTR::init_ctr(struct ctr_state *state, const unsigned char iv[8]){
state->num = 0;
memset(state->ecount, 0, AES_BLOCK_SIZE);
memset(state->ivec + 8, 0, 8);
memcpy(state->ivec, iv, 8);
return 0;
}
// encrypt twice == decrypt
void CAESCTR::encrypt(unsigned char *indata, unsigned char *outdata, int bytes_read){
int i = 0;
int mod_len = 0;
AES_set_encrypt_key(ckey, KEY_SIZE, &key);
if (bytes_read < BYTES_SIZE){
struct ctr_state state;
init_ctr(&state, iv);
AES_ctr128_encrypt(indata, outdata, bytes_read, &key, state.ivec, state.ecount, &state.num);
return;
}
// loop block size = [ BYTES_SIZE ]
for (i = BYTES_SIZE; i <= bytes_read; i += BYTES_SIZE){
struct ctr_state state;
init_ctr(&state, iv);
AES_ctr128_encrypt(indata, outdata, BYTES_SIZE, &key, state.ivec, state.ecount, &state.num);
indata += BYTES_SIZE;
outdata += BYTES_SIZE;
}
mod_len = bytes_read % BYTES_SIZE;
if (mod_len != 0){
struct ctr_state state;
init_ctr(&state, iv);
AES_ctr128_encrypt(indata, outdata, mod_len, &key, state.ivec, state.ecount, &state.num);
}
}
void CAESCTR::encrypt(CString& instr, CString& outstr, int bytes_read){
int i = 0;
int mod_len = 0;
unsigned char *indata;
unsigned char *outdata;
indata = (unsigned char *)malloc(instr.GetLength() + 1);
outdata = (unsigned char *)malloc(instr.GetLength() + 1);
strncpy((char*)indata, (LPSTR)(LPCSTR)instr, instr.GetLength());
indata[instr.GetLength()] = NULL;
AES_set_encrypt_key(ckey, KEY_SIZE, &key);
if (bytes_read < BYTES_SIZE){
struct ctr_state state;
init_ctr(&state, iv);
AES_ctr128_encrypt(indata, outdata, bytes_read, &key, state.ivec, state.ecount, &state.num);
outdata[instr.GetLength()] = NULL;
outstr = outdata;
return;
}
// loop block size = [ BYTES_SIZE ]
for (i = BYTES_SIZE; i <= bytes_read; i += BYTES_SIZE){
struct ctr_state state;
init_ctr(&state, iv);
AES_ctr128_encrypt(indata, outdata, BYTES_SIZE, &key, state.ivec, state.ecount, &state.num);
indata += BYTES_SIZE;
outdata += BYTES_SIZE;
}
mod_len = bytes_read % BYTES_SIZE;
if (mod_len != 0){
struct ctr_state state;
init_ctr(&state, iv);
AES_ctr128_encrypt(indata, outdata, mod_len, &key, state.ivec, state.ecount, &state.num);
}
outdata[instr.GetLength()] = NULL;
outstr = outdata;
}
CAESCTR::CAESCTR()
{
unsigned char temp_iv[8] = { 0x66, 0x61, 0x63, 0x65, 0x73, 0x65, 0x61, 0x00 };
memcpy(iv, temp_iv, 8);
unsigned char temp_ckey[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 }; // 32bytes = AES256, 16bytes = AES128
memcpy(ckey, temp_ckey, 32);
}
CAESCTR::CAESCTR(unsigned char* iv, unsigned char* ckey)
{
memcpy(this->iv, iv, 8);
memcpy(this->ckey, ckey, 32);
}
CAESCTR::~CAESCTR()
{
}
그리고, 프로젝트 속성에서
구성 속성 > 문자 집합 > 설정 안 함
으로 하여서 사용하였습니다.
사용예시
void CPasswordEncoderDlg::OnEnChangeEdit1()
{
// TODO: RICHEDIT 컨트롤인 경우, 이 컨트롤은
// CDialogEx::OnInitDialog() 함수를 재지정
//하고 마스크에 OR 연산하여 설정된 ENM_CHANGE 플래그를 지정하여 CRichEditCtrl().SetEventMask()를 호출하지 않으면
// 이 알림 메시지를 보내지 않습니다.
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
CAESCTR m_AESCTR;
CString editText;
m_Edit1.GetWindowTextA(editText);
int editTextLength = editText.GetLength();
unsigned char* editTextCharSeq;
editTextCharSeq = (unsigned char *)malloc(editTextLength+1);
strncpy((char*)editTextCharSeq, (LPSTR)(LPCSTR)editText, editTextLength);
editTextCharSeq[editTextLength] = NULL;
unsigned char* outTextCharSeq;
outTextCharSeq = (unsigned char *)malloc(editTextLength + 1);
m_AESCTR.encrypt(editTextCharSeq, outTextCharSeq, editTextLength);
outTextCharSeq[editTextLength] = NULL;
editText = outTextCharSeq;
m_Edit2.SetWindowTextA(editText);
m_AESCTR.encrypt(editText, editText, editTextLength);
m_Edit3.SetWindowTextA(editText);
free(editTextCharSeq);
free(outTextCharSeq);
}
'Programming > C,CPP,CS' 카테고리의 다른 글
| openssl AES encrypt (AES_ctr128_encrypt) (0) | 2016.09.19 |
|---|---|
| openssl AES Mode : ECB, CBC, CFB, OFB, CTR (0) | 2016.09.05 |
| CDateTimeCtrl 사용법 (0) | 2016.08.25 |
| Apache License, Version 2.0 (0) | 2016.08.22 |
| Log4cxx ChainSaw Appender (0) | 2016.08.22 |



