1: <?php namespace Laravel; defined('DS') or die('No direct script access.');
2:
3: class Crypter {
4:
5: /**
6: * The encryption cipher.
7: *
8: * @var string
9: */
10: public static $cipher = MCRYPT_RIJNDAEL_256;
11:
12: /**
13: * The encryption mode.
14: *
15: * @var string
16: */
17: public static $mode = MCRYPT_MODE_CBC;
18:
19: /**
20: * The block size of the cipher.
21: *
22: * @var int
23: */
24: public static $block = 32;
25:
26: /**
27: * Encrypt a string using Mcrypt.
28: *
29: * The string will be encrypted using the AES-256 scheme and will be base64 encoded.
30: *
31: * @param string $value
32: * @return string
33: */
34: public static function encrypt($value)
35: {
36: $iv = mcrypt_create_iv(static::iv_size(), static::randomizer());
37:
38: $value = static::pad($value);
39:
40: $value = mcrypt_encrypt(static::$cipher, static::key(), $value, static::$mode, $iv);
41:
42: return base64_encode($iv.$value);
43: }
44:
45: /**
46: * Decrypt a string using Mcrypt.
47: *
48: * @param string $value
49: * @return string
50: */
51: public static function decrypt($value)
52: {
53: $value = base64_decode($value);
54:
55: // To decrypt the value, we first need to extract the input vector and
56: // the encrypted value. The input vector size varies across different
57: // encryption ciphers and modes, so we'll get the correct size.
58: $iv = substr($value, 0, static::iv_size());
59:
60: $value = substr($value, static::iv_size());
61:
62: // Once we have the input vector and the value, we can give them both
63: // to Mcrypt for decryption. The value is sometimes padded with \0,
64: // so we will trim all of the padding characters.
65: $key = static::key();
66:
67: $value = mcrypt_decrypt(static::$cipher, $key, $value, static::$mode, $iv);
68:
69: return static::unpad($value);
70: }
71:
72: /**
73: * Get the most secure random number generator for the system.
74: *
75: * @return int
76: */
77: public static function randomizer()
78: {
79: // There are various sources from which we can get random numbers
80: // but some are more random than others. We'll choose the most
81: // random source we can for this server environment.
82: if (defined('MCRYPT_DEV_URANDOM'))
83: {
84: return MCRYPT_DEV_URANDOM;
85: }
86: elseif (defined('MCRYPT_DEV_RANDOM'))
87: {
88: return MCRYPT_DEV_RANDOM;
89: }
90: // When using the default random number generator, we'll seed
91: // the generator on each call to ensure the results are as
92: // random as we can possibly get them.
93: else
94: {
95: mt_srand();
96:
97: return MCRYPT_RAND;
98: }
99: }
100:
101: /**
102: * Get the input vector size for the cipher and mode.
103: *
104: * @return int
105: */
106: protected static function iv_size()
107: {
108: return mcrypt_get_iv_size(static::$cipher, static::$mode);
109: }
110:
111: /**
112: * Add PKCS7 compatible padding on the given value.
113: *
114: * @param string $value
115: * @return string
116: */
117: protected static function pad($value)
118: {
119: $pad = static::$block - (strlen($value) % static::$block);
120:
121: return $value .= str_repeat(chr($pad), $pad);
122: }
123:
124: /**
125: * Remove the PKCS7 compatible padding from the given value.
126: *
127: * @param string $value
128: * @return string
129: */
130: protected static function unpad($value)
131: {
132: $pad = ord(substr($value, -1));
133:
134: if ($pad and $pad <= static::$block)
135: {
136: // If the correct padding is present on the string, we will remove
137: // it and return the value. Otherwise, we'll throw an exception
138: // as the padding appears to have been changed.
139: if (preg_match('/'.chr($pad).'{'.$pad.'}$/', $value))
140: {
141: return substr($value, 0, strlen($value) - $pad);
142: }
143:
144: // If the padding characters do not match the expected padding
145: // for the value we'll bomb out with an exception since the
146: // encrypted value seems to have been changed.
147: else
148: {
149: throw new \Exception("Decryption error. Padding is invalid.");
150: }
151: }
152:
153: return $value;
154: }
155:
156: /**
157: * Get the encryption key from the application configuration.
158: *
159: * @return string
160: */
161: protected static function key()
162: {
163: return Config::get('application.key');
164: }
165:
166: }
167: