336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
CPP 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 빌드 : http://yokkohama.tistory.com/entry/OpenSSL-%EB%B9%8C%EB%93%9C%ED%95%98%EA%B8%B0-Visual-Studio-2010-%EB%98%90%EB%8A%94-libeay32dll-ssleay32dll-%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C
"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);
}