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