2016. 5. 10. 15:11

AES128 CBC PKCS5 HMAC(SHA256) 암/복호화(PHP)

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!= $padreturn false;
        return substr($text0-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($cipher0$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)

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 - 3232);
 
            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;
        }
    }
}



2016. 5. 10. 15:03

AES128 CBC PKCS5 HMAC(SHA256) 암/복호화(C++)

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, truenew CryptoPP::StreamTransformationFilter(e, new CryptoPP::StringSink(cipher), CryptoPP::BlockPaddingSchemeDef::PKCS_PADDING));
        CryptoPP::HMAC<CryptoPP::SHA256> hmac_hash(hashKey, sizeof(hashKey));
        CryptoPP::StringSource(cipher, truenew CryptoPP::HashFilter(hmac_hash, new CryptoPP::StringSink(hmac)));
        CryptoPP::StringSource(cipher + hmac, truenew 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, truenew 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() - 3232);
 
        CryptoPP::HMAC<CryptoPP::SHA256> hmac_hash(hashKey, sizeof(hashKey));
        CryptoPP::StringSource(cipher, truenew 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, truenew 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();
    }
}
 
 



2016. 5. 10. 10:03

[Visual Studio Code, VS Code] 관련 팁

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\""

}