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