Projekt

Obecné

Profil

Stáhnout (5.46 KB) Statistiky
| Větev: | Revize:
1
<?php
2

    
3
namespace Illuminate\Encryption;
4

    
5
use Exception;
6
use RuntimeException;
7
use Illuminate\Contracts\Encryption\DecryptException;
8
use Illuminate\Contracts\Encryption\EncryptException;
9
use Illuminate\Contracts\Encryption\Encrypter as EncrypterContract;
10

    
11
/**
12
 * @deprecated since version 5.1. Use Illuminate\Encryption\Encrypter.
13
 */
14
class McryptEncrypter extends BaseEncrypter implements EncrypterContract
15
{
16
    /**
17
     * The algorithm used for encryption.
18
     *
19
     * @var string
20
     */
21
    protected $cipher;
22

    
23
    /**
24
     * The block size of the cipher.
25
     *
26
     * @var int
27
     */
28
    protected $block;
29

    
30
    /**
31
     * Create a new encrypter instance.
32
     *
33
     * @param  string  $key
34
     * @param  string  $cipher
35
     * @return void
36
     *
37
     * @throws \RuntimeException
38
     */
39
    public function __construct($key, $cipher = MCRYPT_RIJNDAEL_128)
40
    {
41
        $key = (string) $key;
42

    
43
        if (static::supported($key, $cipher)) {
44
            $this->key = $key;
45
            $this->cipher = $cipher;
46
            $this->block = mcrypt_get_iv_size($this->cipher, MCRYPT_MODE_CBC);
47
        } else {
48
            throw new RuntimeException('The only supported ciphers are MCRYPT_RIJNDAEL_128 and MCRYPT_RIJNDAEL_256.');
49
        }
50
    }
51

    
52
    /**
53
     * Determine if the given key and cipher combination is valid.
54
     *
55
     * @param  string  $key
56
     * @param  string  $cipher
57
     * @return bool
58
     */
59
    public static function supported($key, $cipher)
60
    {
61
        return defined('MCRYPT_RIJNDAEL_128') &&
62
                ($cipher === MCRYPT_RIJNDAEL_128 || $cipher === MCRYPT_RIJNDAEL_256);
63
    }
64

    
65
    /**
66
     * Encrypt the given value.
67
     *
68
     * @param  string  $value
69
     * @return string
70
     *
71
     * @throws \Illuminate\Contracts\Encryption\EncryptException
72
     */
73
    public function encrypt($value)
74
    {
75
        $iv = mcrypt_create_iv($this->getIvSize(), $this->getRandomizer());
76

    
77
        $value = base64_encode($this->padAndMcrypt($value, $iv));
78

    
79
        // Once we have the encrypted value we will go ahead base64_encode the input
80
        // vector and create the MAC for the encrypted value so we can verify its
81
        // authenticity. Then, we'll JSON encode the data in a "payload" array.
82
        $mac = $this->hash($iv = base64_encode($iv), $value);
83

    
84
        $json = json_encode(compact('iv', 'value', 'mac'));
85

    
86
        if (! is_string($json)) {
87
            throw new EncryptException('Could not encrypt the data.');
88
        }
89

    
90
        return base64_encode($json);
91
    }
92

    
93
    /**
94
     * Pad and use mcrypt on the given value and input vector.
95
     *
96
     * @param  string  $value
97
     * @param  string  $iv
98
     * @return string
99
     */
100
    protected function padAndMcrypt($value, $iv)
101
    {
102
        $value = $this->addPadding(serialize($value));
103

    
104
        return mcrypt_encrypt($this->cipher, $this->key, $value, MCRYPT_MODE_CBC, $iv);
105
    }
106

    
107
    /**
108
     * Decrypt the given value.
109
     *
110
     * @param  string  $payload
111
     * @return string
112
     */
113
    public function decrypt($payload)
114
    {
115
        $payload = $this->getJsonPayload($payload);
116

    
117
        // We'll go ahead and remove the PKCS7 padding from the encrypted value before
118
        // we decrypt it. Once we have the de-padded value, we will grab the vector
119
        // and decrypt the data, passing back the unserialized from of the value.
120
        $value = base64_decode($payload['value']);
121

    
122
        $iv = base64_decode($payload['iv']);
123

    
124
        return unserialize($this->stripPadding($this->mcryptDecrypt($value, $iv)));
125
    }
126

    
127
    /**
128
     * Run the mcrypt decryption routine for the value.
129
     *
130
     * @param  string  $value
131
     * @param  string  $iv
132
     * @return string
133
     *
134
     * @throws \Illuminate\Contracts\Encryption\DecryptException
135
     */
136
    protected function mcryptDecrypt($value, $iv)
137
    {
138
        try {
139
            return mcrypt_decrypt($this->cipher, $this->key, $value, MCRYPT_MODE_CBC, $iv);
140
        } catch (Exception $e) {
141
            throw new DecryptException($e->getMessage());
142
        }
143
    }
144

    
145
    /**
146
     * Add PKCS7 padding to a given value.
147
     *
148
     * @param  string  $value
149
     * @return string
150
     */
151
    protected function addPadding($value)
152
    {
153
        $pad = $this->block - (strlen($value) % $this->block);
154

    
155
        return $value.str_repeat(chr($pad), $pad);
156
    }
157

    
158
    /**
159
     * Remove the padding from the given value.
160
     *
161
     * @param  string  $value
162
     * @return string
163
     */
164
    protected function stripPadding($value)
165
    {
166
        $pad = ord($value[($len = strlen($value)) - 1]);
167

    
168
        return $this->paddingIsValid($pad, $value) ? substr($value, 0, $len - $pad) : $value;
169
    }
170

    
171
    /**
172
     * Determine if the given padding for a value is valid.
173
     *
174
     * @param  string  $pad
175
     * @param  string  $value
176
     * @return bool
177
     */
178
    protected function paddingIsValid($pad, $value)
179
    {
180
        $beforePad = strlen($value) - $pad;
181

    
182
        return substr($value, $beforePad) == str_repeat(substr($value, -1), $pad);
183
    }
184

    
185
    /**
186
     * Get the IV size for the cipher.
187
     *
188
     * @return int
189
     */
190
    protected function getIvSize()
191
    {
192
        return mcrypt_get_iv_size($this->cipher, MCRYPT_MODE_CBC);
193
    }
194

    
195
    /**
196
     * Get the random data source available for the OS.
197
     *
198
     * @return int
199
     */
200
    protected function getRandomizer()
201
    {
202
        if (defined('MCRYPT_DEV_URANDOM')) {
203
            return MCRYPT_DEV_URANDOM;
204
        }
205

    
206
        if (defined('MCRYPT_DEV_RANDOM')) {
207
            return MCRYPT_DEV_RANDOM;
208
        }
209

    
210
        mt_srand();
211

    
212
        return MCRYPT_RAND;
213
    }
214
}
(4-4/5)