2014. 12. 5. 10:44

AES CBC 128BIT PKCS5 암/복호화(C++)

Crypto++ 라이브러리를 이용함 암/복호화

(AES CBC 128BIT PKCS5)


#include "UtilsCrypto.h" //헤더는 별내용 없음 #include "cryptopp/cryptlib.h" #include "cryptopp/modes.h" #include "cryptopp/aes.h" #include "cryptopp/filters.h" #include "cryptopp/base64.h" #include "cryptopp/md5.h" #include "cryptopp/hex.h" UtilsCrypto::UtilsCrypto(void) { } UtilsCrypto::~UtilsCrypto(void) { } void UtilsCrypto::hex2byte(const char *in, _UInt32 len, byte *out)

{ for(_UInt32 i = 0; i < len; i+=2) { char c0 = in[i+0]; char c1 = in[i+1]; byte c = ( ((c0 & 0x40 ? (c0 & 0x20 ? c0 - 0x57 : c0 - 0x37) : c0 - 0x30) << 4) | ((c1 & 0x40 ? (c1 & 0x20 ? c1 - 0x57 : c1 - 0x37) : c1 - 0x30)) ); out[i/2] = c; } } std::string UtilsCrypto::MD5HASH(std::string str)

{ CryptoPP::MD5 hash; byte digest[CryptoPP::MD5::DIGESTSIZE]; hash.CalculateDigest(digest, (byte*)str.c_str(), str.length()); CryptoPP::HexEncoder encoder; std::string output; encoder.Attach(new CryptoPP::StringSink(output)); encoder.Put(digest, sizeof(digest)); encoder.MessageEnd(); return output; } std::string UtilsCrypto::encrypt(std::string str)

{ std::string enc_key = MD5HASH("암호키"); std::string enc_iv = MD5HASH("iv키"); //키할당 byte key[CryptoPP::AES::DEFAULT_KEYLENGTH]; memset(key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH); const char* rawKey = enc_key.c_str(); hex2byte(rawKey, strlen(rawKey), key); //iv할당 byte iv[CryptoPP::AES::BLOCKSIZE]; memset(iv, 0x00, CryptoPP::AES::BLOCKSIZE); const char* rawIv = enc_iv.c_str(); hex2byte(rawIv, strlen(rawIv), iv); std::string cipher, encoded; try { CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption e; e.SetKeyWithIV(key, sizeof(key), iv); CryptoPP::StringSource ss(str, true, new CryptoPP::StreamTransformationFilter(e, new CryptoPP::StringSink(cipher), CryptoPP::BlockPaddingSchemeDef::PKCS_PADDING)); CryptoPP::StringSource(cipher, true, new CryptoPP::Base64Encoder(new CryptoPP::StringSink(encoded), false)); //base64encoder 두번째 인자에 false를 줘야 마지막애 개행문자가 추가안됨 return encoded; } catch(const CryptoPP::Exception& e) { std::cerr << e.what() << std::endl; return NULL; } } std::string UtilsCrypto::decrypt(std::string str)

{ std::string enc_key = MD5HASH("암호키"); std::string enc_iv = MD5HASH("iv키"); //키할당 byte key[CryptoPP::AES::DEFAULT_KEYLENGTH]; memset(key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH); const char* rawKey = enc_key.c_str(); hex2byte(rawKey, strlen(rawKey), key); //iv할당 byte iv[CryptoPP::AES::BLOCKSIZE]; memset(iv, 0x00, CryptoPP::AES::BLOCKSIZE); const char* rawIv = enc_iv.c_str(); hex2byte(rawIv, strlen(rawIv), iv); std::string cipher, decoded; try { CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption d; d.SetKeyWithIV(key, sizeof(key), iv); CryptoPP::StringSource(str, true, new CryptoPP::Base64Decoder(new CryptoPP::StringSink(cipher))); CryptoPP::StringSource ss(cipher, true, new CryptoPP::StreamTransformationFilter(d, new CryptoPP::StringSink(decoded), CryptoPP::BlockPaddingSchemeDef::PKCS_PADDING)); return decoded; } catch(const CryptoPP::Exception& e) { std::cerr << e.what() << std::endl; return NULL; } }