1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | <?php namespace Lib; define('ENC_KEY', hex2bin(md5('비밀키'))); define('ENC_IV', hex2bin(md5('IV키'))); define('ENC_HASH', hex2bin(md5('HMAC키'))); class Mcrypt { /** * PKCS5 패드추가 * @param string $text * @param int $blocksize * @return string */ public static function pkcs5_pad ($text, $blocksize) { $pad = $blocksize - (strlen($text) % $blocksize); return $text . str_repeat(chr($pad), $pad); } /** * PKCS5 패드제거 * @param string $text * @return boolean|string */ public static function pkcs5_unpad($text) { $pad = ord($text{strlen($text)-1}); if ($pad > strlen($text)) return false; if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false; return substr($text, 0, -1 * $pad); } /** * 암호화 * @param string $str * @return string */ public static function encrypt($str) { $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, 'cbc'); $input = self::pkcs5_pad($str, $size); $cipher = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, ENC_KEY, $input, MCRYPT_MODE_CBC, ENC_IV); $hmac = hash_hmac('sha256', $cipher, ENC_HASH, true); return base64_encode($cipher.$hmac); } /** * 복호화 * @param string $str * @return bool|string */ public static function decrypt($str) { $cipher = @base64_decode($str); if($cipher === false) return false; $len = strlen($cipher); if($len < 48) return false; $hmac = substr($cipher, -32); $ciphertext = substr($cipher, 0, $len - 32); $hmac_check = hash_hmac('sha256', $ciphertext, ENC_HASH, true); if($hmac !== $hmac_check) return false; $plaintext = @mcrypt_decrypt(MCRYPT_RIJNDAEL_128, ENC_KEY, $ciphertext, MCRYPT_MODE_CBC, ENC_IV); if($plaintext === false) return false; else return self::pkcs5_unpad($plaintext); } } |
2016. 5. 10. 15:08
AES128 CBC PKCS5 HMAC(SHA256) 암/복호화(AS3)
2016. 5. 10. 15:08 in 자작소스/ActionScript3

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | package com.citrus.lib.misc { import com.adobe.crypto.MD5; import com.hurlant.crypto.Crypto; import com.hurlant.crypto.hash.HMAC; import com.hurlant.crypto.hash.SHA256; import com.hurlant.crypto.symmetric.ICipher; import com.hurlant.crypto.symmetric.IPad; import com.hurlant.crypto.symmetric.IVMode; import com.hurlant.crypto.symmetric.PKCS5; import com.hurlant.util.Base64; import com.hurlant.util.Hex; import flash.utils.ByteArray; public class As3Crypto { public static var ENC_KEY:String = MD5.hash("비밀키"); public static var ENC_IV:String = MD5.hash("IV키"); public static var ENC_HASH:String = MD5.hash("HMAC키"); public static function encrypt(str:String):String { var data:ByteArray = Hex.toArray(Hex.fromString(str)); var kdata:ByteArray = Hex.toArray(ENC_KEY); var pad:IPad = new PKCS5(); var cipher:ICipher = Crypto.getCipher('aes-128-cbc', kdata, pad); pad.setBlockSize(cipher.getBlockSize()); if(cipher is IVMode) { var ivmode:IVMode = cipher as IVMode; ivmode.IV = Hex.toArray(ENC_IV); } cipher.encrypt(data); return Base64.encodeByteArray(data); } public static function decrypt(str:String):String { var data:ByteArray = Base64.decodeToByteArray(str); var kdata:ByteArray = Hex.toArray(ENC_KEY); var pad:IPad = new PKCS5(); var cipher:ICipher = Crypto.getCipher('aes-128-cbc', kdata, pad); pad.setBlockSize(cipher.getBlockSize()); if(cipher is IVMode) { var ivmode:IVMode = cipher as IVMode; ivmode.IV = Hex.toArray(ENC_IV); } cipher.decrypt(data); return Hex.toString(Hex.fromArray(data)); } public static function encryptHmac(str:String):String { var data:ByteArray = Hex.toArray(Hex.fromString(str)); var kdata:ByteArray = Hex.toArray(ENC_KEY); var pad:IPad = new PKCS5(); var cipher:ICipher = Crypto.getCipher('aes-128-cbc', kdata, pad); pad.setBlockSize(cipher.getBlockSize()); if(cipher is IVMode) { var ivmode:IVMode = cipher as IVMode; ivmode.IV = Hex.toArray(ENC_IV); } cipher.encrypt(data); var hmac:HMAC = new HMAC(new SHA256()); var hmacValue:ByteArray = hmac.compute(Hex.toArray(ENC_HASH), data); var encoded:ByteArray = new ByteArray(); encoded.writeBytes(data); encoded.writeBytes(hmacValue); return Base64.encodeByteArray(encoded); } public static function decryptHmac(str:String):String { if(str.length == 0) return ""; var data:ByteArray = Base64.decodeToByteArray(str); var len:uint = data.length; if(len < 48) return ""; var dataByte:ByteArray = new ByteArray(); dataByte.writeBytes(data, 0, len - 32); var hmacByte:ByteArray = new ByteArray(); hmacByte.writeBytes(data, len - 32, 32); var hmac:HMAC = new HMAC(new SHA256()); var hmacValue:ByteArray = hmac.compute(Hex.toArray(ENC_HASH), dataByte); if(!compareByteArray(hmacByte, hmacValue)) return ""; var kdata:ByteArray = Hex.toArray(ENC_KEY); var pad:IPad = new PKCS5(); var cipher:ICipher = Crypto.getCipher('aes-128-cbc', kdata, pad); pad.setBlockSize(cipher.getBlockSize()); if(cipher is IVMode) { var ivmode:IVMode = cipher as IVMode; ivmode.IV = Hex.toArray(ENC_IV); } cipher.decrypt(dataByte); return Hex.toString(Hex.fromArray(dataByte)); } public static function compareByteArray(arr1:ByteArray, arr2:ByteArray):Boolean { if(arr1.length != arr2.length) return false; for(var i:int=0, cnt:int = arr1.length; i < cnt; ++i) { if(arr1[i] != arr2[i]) return false; } return true; } } } |
1. 헤더파일
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #ifndef UTILS_CRYPTO_H #define UTILS_CRYPTO_H #include <string> #include <stdio.h> #include "os/Compat.h" #include "cryptopp/config.h" class UtilsCrypto { public: UtilsCrypto(void); ~UtilsCrypto(void); static void hex2byte(const char *in, _UInt32 len, byte *out); static std::string MD5HASH(std::string); static std::string SHA256HASH(std::string); static std::string encrypt(std::string); static std::string decrypt(std::string); }; #endif |
2. cpp파일
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | #define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 #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" #include "cryptopp/sha.h" #include "cryptopp/hmac.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::Weak::MD5 hash; byte digest[CryptoPP::Weak::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::SHA256HASH(std::string str) { byte const* pbData = (byte*)str.data(); _UInt32 nDataLen = str.size(); byte abDigest[CryptoPP::SHA256::DIGESTSIZE]; CryptoPP::SHA256().CalculateDigest(abDigest, pbData, nDataLen); return std::string((char*)abDigest, 32); } std::string UtilsCrypto::encrypt(std::string str) { if (str.empty()) return std::string(); std::string enc_key = MD5HASH("비밀키"); std::string enc_iv = MD5HASH("IV키"); std::string enc_hash = MD5HASH("HMAC키"); //키할당 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); //hash키할당 byte hashKey[CryptoPP::AES::DEFAULT_KEYLENGTH]; memset(hashKey, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH); const char* rawHashKey = enc_hash.c_str(); hex2byte(rawHashKey, strlen(rawHashKey), hashKey); std::string cipher, hmac, 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::HMAC<CryptoPP::SHA256> hmac_hash(hashKey, sizeof(hashKey)); CryptoPP::StringSource(cipher, true, new CryptoPP::HashFilter(hmac_hash, new CryptoPP::StringSink(hmac))); CryptoPP::StringSource(cipher + hmac, true, new CryptoPP::Base64Encoder(new CryptoPP::StringSink(encoded), false)); return encoded; } catch (const CryptoPP::Exception &e) { std::cerr << e.what() << std::endl; return std::string(); } } std::string UtilsCrypto::decrypt(std::string str) { if (str.empty()) return std::string(); std::string enc_key = MD5HASH("비밀키"); std::string enc_iv = MD5HASH("IV키"); std::string enc_hash = MD5HASH("HMAC키"); //키할당 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); //hash키할당 byte hashKey[CryptoPP::AES::DEFAULT_KEYLENGTH]; memset(hashKey, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH); const char* rawHashKey = enc_hash.c_str(); hex2byte(rawHashKey, strlen(rawHashKey), hashKey); std::string tmp, cipher, hmac, hmac2, decoded; try { CryptoPP::StringSource(str, true, new CryptoPP::Base64Decoder(new CryptoPP::StringSink(tmp))); if (tmp.size() < 48) return std::string(); cipher = tmp.substr(0, tmp.size() - 32); hmac = tmp.substr(tmp.size() - 32, 32); CryptoPP::HMAC<CryptoPP::SHA256> hmac_hash(hashKey, sizeof(hashKey)); CryptoPP::StringSource(cipher, true, new CryptoPP::HashFilter(hmac_hash, new CryptoPP::StringSink(hmac2))); if (hmac.compare(hmac2) != 0) return std::string(); CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption d; d.SetKeyWithIV(key, sizeof(key), iv); 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 std::string(); } } |
1. 확장설치/업데이트/설치된 목록
명령파렛트(Ctrl + Shift + P) 를 띄운 후 꺽쇠 > 를 지우고 입력
그리고 명령 입력 후 반드시 한칸(Space)을 띄워야 명령어가 인식이 되니 주의
ext : 설치된 확장 보기, 선택해서 삭제
ext install : 설치가능한 확장 보기
ext update : 업데이트 가능한 확장 보기
2. 프로젝트 경로에 콘솔창(ConEmu) 띄우기
터미널을 띄울 경우(Ctrl + Shift + C) 기본 커맨드쉘(cmd.exe)가 뜨는데 ConEmu로 바꾸는 방법
Open in User-defined Consol 확장을 설치
settings.json 에 아래 내용을 추가(경로는 맞게 수정)
{
"console.executable": "cmd.exe",
"console.args": "/s /c \"\"D:\\유틸\\ConEmuPack.150813c\\ConEmu64.exe\" /single\""
}