PluginProbe ʕ •ᴥ•ʔ
JetBackup – Backup, Restore & Migrate / trunk
JetBackup – Backup, Restore & Migrate vtrunk
3.1.22.4 3.1.22.3 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.8.1 1.4.9 1.5.0 1.5.1 1.5.1.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.10 1.6.11 1.6.12 1.6.13 1.6.15 1.6.5.1 1.6.8.8 1.6.9 1.6.9.1 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7.5 2.0.8.7 2.0.9.11 2.0.9.14 2.0.9.15 2.0.9.6 2.0.9.7 2.0.9.9 3.1.10.7 3.1.11.1 3.1.12.3 3.1.13.4 3.1.14.17 3.1.15.4 3.1.16.1 3.1.17.5 3.1.18.10 3.1.18.8 3.1.18.9 3.1.19.8 3.1.20.3 3.1.21.3 3.1.7.9 3.1.9.2 trunk 1.1.90 1.1.91 1.2.0 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2
backup / src / JetBackup / 3rdparty / phpseclib3 / Crypt / TripleDES.php
backup / src / JetBackup / 3rdparty / phpseclib3 / Crypt Last commit date
Common 1 year ago DH 1 year ago DSA 1 year ago EC 1 year ago RSA 1 year ago .htaccess 1 year ago AES.php 1 year ago Blowfish.php 1 year ago ChaCha20.php 1 year ago DES.php 1 year ago DH.php 1 year ago DSA.php 1 year ago EC.php 1 year ago Hash.php 1 year ago PublicKeyLoader.php 1 year ago RC2.php 1 year ago RC4.php 1 year ago RSA.php 1 year ago Random.php 1 year ago Rijndael.php 1 year ago Salsa20.php 1 year ago TripleDES.php 1 year ago Twofish.php 1 year ago index.html 1 year ago web.config 1 year ago
TripleDES.php
416 lines
1 <?php
2
3 /**
4 * Pure-PHP implementation of Triple DES.
5 *
6 * Uses OpenSSL, if available/possible, and an internal implementation, otherwise.
7 *
8 * Operates in the EDE3 mode (encrypt-decrypt-encrypt).
9 *
10 * PHP version 5
11 *
12 * Here's a short example of how to use this library:
13 * <code>
14 * <?php
15 * include 'vendor/autoload.php';
16 *
17 * $des = new \phpseclib3\Crypt\TripleDES('ctr');
18 *
19 * $des->setKey('abcdefghijklmnopqrstuvwx');
20 *
21 * $size = 10 * 1024;
22 * $plaintext = '';
23 * for ($i = 0; $i < $size; $i++) {
24 * $plaintext.= 'a';
25 * }
26 *
27 * echo $des->decrypt($des->encrypt($plaintext));
28 * ?>
29 * </code>
30 *
31 * @author Jim Wigginton <terrafrost@php.net>
32 * @copyright 2007 Jim Wigginton
33 * @license http://www.opensource.org/licenses/mit-license.html MIT License
34 * @link http://phpseclib.sourceforge.net
35 */
36
37 declare(strict_types=1);
38
39 namespace phpseclib3\Crypt;
40
41 use phpseclib3\Exception\BadModeException;
42 use phpseclib3\Exception\LengthException;
43
44 /**
45 * Pure-PHP implementation of Triple DES.
46 *
47 * @author Jim Wigginton <terrafrost@php.net>
48 */
49 class TripleDES extends DES
50 {
51 /**
52 * Encrypt / decrypt using inner chaining
53 *
54 * Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (self::MODE_CBC3).
55 */
56 public const MODE_3CBC = -2;
57
58 /**
59 * Encrypt / decrypt using outer chaining
60 *
61 * Outer chaining is used by SSH-2 and when the mode is set to \phpseclib3\Crypt\Common\BlockCipher::MODE_CBC.
62 */
63 public const MODE_CBC3 = self::MODE_CBC;
64
65 /**
66 * Key Length (in bytes)
67 *
68 * @see \phpseclib3\Crypt\TripleDES::setKeyLength()
69 * @var int
70 */
71 protected $key_length = 24;
72
73 /**
74 * max possible size of $key
75 *
76 * @see self::setKey()
77 * @see \phpseclib3\Crypt\DES::setKey()
78 * @var string
79 */
80 protected $key_length_max = 24;
81
82 /**
83 * Internal flag whether using self::MODE_3CBC or not
84 *
85 * @var bool
86 */
87 private $mode_3cbc;
88
89 /**
90 * The \phpseclib3\Crypt\DES objects
91 *
92 * Used only if $mode_3cbc === true
93 *
94 * @var array
95 */
96 private $des;
97
98 /**
99 * Default Constructor.
100 *
101 * $mode could be:
102 *
103 * - ecb
104 *
105 * - cbc
106 *
107 * - ctr
108 *
109 * - cfb
110 *
111 * - ofb
112 *
113 * - 3cbc
114 *
115 * - cbc3 (same as cbc)
116 *
117 * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct()
118 * @see \phpseclib3\Crypt\DES::__construct()
119 */
120 public function __construct(string $mode)
121 {
122 switch (strtolower($mode)) {
123 // In case of self::MODE_3CBC, we init as CRYPT_DES_MODE_CBC
124 // and additional flag us internally as 3CBC
125 case '3cbc':
126 parent::__construct('cbc');
127 $this->mode_3cbc = true;
128
129 // This three $des'es will do the 3CBC work (if $key > 64bits)
130 $this->des = [
131 new DES('cbc'),
132 new DES('cbc'),
133 new DES('cbc'),
134 ];
135
136 // we're going to be doing the padding, ourselves, so disable it in the \phpseclib3\Crypt\DES objects
137 $this->des[0]->disablePadding();
138 $this->des[1]->disablePadding();
139 $this->des[2]->disablePadding();
140 break;
141 case 'cbc3':
142 $mode = 'cbc';
143 // fall-through
144 // If not 3CBC, we init as usual
145 default:
146 parent::__construct($mode);
147
148 if ($this->mode == self::MODE_STREAM) {
149 throw new BadModeException('Block ciphers cannot be ran in stream mode');
150 }
151 }
152 }
153
154 /**
155 * Test for engine validity
156 *
157 * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine()
158 *
159 * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct()
160 */
161 protected function isValidEngineHelper(int $engine): bool
162 {
163 if ($engine == self::ENGINE_OPENSSL) {
164 $this->cipher_name_openssl_ecb = 'des-ede3';
165 $mode = $this->openssl_translate_mode();
166 $this->cipher_name_openssl = $mode == 'ecb' ? 'des-ede3' : 'des-ede3-' . $mode;
167 }
168
169 return parent::isValidEngineHelper($engine);
170 }
171
172 /**
173 * Sets the initialization vector.
174 *
175 * SetIV is not required when \phpseclib3\Crypt\Common\SymmetricKey::MODE_ECB is being used.
176 *
177 * @see \phpseclib3\Crypt\Common\SymmetricKey::setIV()
178 */
179 public function setIV(string $iv): void
180 {
181 parent::setIV($iv);
182 if ($this->mode_3cbc) {
183 $this->des[0]->setIV($iv);
184 $this->des[1]->setIV($iv);
185 $this->des[2]->setIV($iv);
186 }
187 }
188
189 /**
190 * Sets the key length.
191 *
192 * Valid key lengths are 128 and 192 bits.
193 *
194 * If you want to use a 64-bit key use DES.php
195 *
196 * @throws LengthException if the key length is invalid
197 * @see \phpseclib3\Crypt\Common\SymmetricKey:setKeyLength()
198 */
199 public function setKeyLength(int $length): void
200 {
201 switch ($length) {
202 case 128:
203 case 192:
204 break;
205 default:
206 throw new LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128 or 192 bits are supported');
207 }
208
209 parent::setKeyLength($length);
210 }
211
212 /**
213 * Sets the key.
214 *
215 * Triple DES can use 128-bit (eg. strlen($key) == 16) or 192-bit (eg. strlen($key) == 24) keys.
216 *
217 * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
218 *
219 * @throws LengthException if the key length is invalid
220 * @see \phpseclib3\Crypt\DES::setKey()
221 * @see \phpseclib3\Crypt\Common\SymmetricKey::setKey()
222 */
223 public function setKey(string $key): void
224 {
225 if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) {
226 throw new LengthException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes');
227 }
228
229 switch (strlen($key)) {
230 case 16:
231 $key .= substr($key, 0, 8);
232 break;
233 case 24:
234 break;
235 default:
236 throw new LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 24 are supported');
237 }
238
239 // copied from self::setKey()
240 $this->key = $key;
241 $this->key_length = strlen($key);
242 $this->changed = $this->nonIVChanged = true;
243 $this->setEngine();
244
245 if ($this->mode_3cbc) {
246 $this->des[0]->setKey(substr($key, 0, 8));
247 $this->des[1]->setKey(substr($key, 8, 8));
248 $this->des[2]->setKey(substr($key, 16, 8));
249 }
250 }
251
252 /**
253 * Encrypts a message.
254 *
255 * @return string $cipertext
256 * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt()
257 */
258 public function encrypt(string $plaintext): string
259 {
260 // parent::en/decrypt() is able to do all the work for all modes and keylengths,
261 // except for: self::MODE_3CBC (inner chaining CBC) with a key > 64bits
262
263 // if the key is smaller then 8, do what we'd normally do
264 if ($this->mode_3cbc && strlen($this->key) > 8) {
265 return $this->des[2]->encrypt(
266 $this->des[1]->decrypt(
267 $this->des[0]->encrypt(
268 $this->pad($plaintext)
269 )
270 )
271 );
272 }
273
274 return parent::encrypt($plaintext);
275 }
276
277 /**
278 * Decrypts a message.
279 *
280 * @return string $plaintext
281 * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt()
282 */
283 public function decrypt(string $ciphertext): string
284 {
285 if ($this->mode_3cbc && strlen($this->key) > 8) {
286 return $this->unpad(
287 $this->des[0]->decrypt(
288 $this->des[1]->encrypt(
289 $this->des[2]->decrypt(
290 str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, "\0")
291 )
292 )
293 )
294 );
295 }
296
297 return parent::decrypt($ciphertext);
298 }
299
300 /**
301 * Treat consecutive "packets" as if they are a continuous buffer.
302 *
303 * Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
304 * will yield different outputs:
305 *
306 * <code>
307 * echo $des->encrypt(substr($plaintext, 0, 8));
308 * echo $des->encrypt(substr($plaintext, 8, 8));
309 * </code>
310 * <code>
311 * echo $des->encrypt($plaintext);
312 * </code>
313 *
314 * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
315 * another, as demonstrated with the following:
316 *
317 * <code>
318 * $des->encrypt(substr($plaintext, 0, 8));
319 * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
320 * </code>
321 * <code>
322 * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
323 * </code>
324 *
325 * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
326 * outputs. The reason is due to the fact that the initialization vector's change after every encryption /
327 * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
328 *
329 * Put another way, when the continuous buffer is enabled, the state of the \phpseclib3\Crypt\DES() object changes after each
330 * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
331 * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
332 * however, they are also less intuitive and more likely to cause you problems.
333 *
334 * @see \phpseclib3\Crypt\Common\SymmetricKey::enableContinuousBuffer()
335 * @see self::disableContinuousBuffer()
336 */
337 public function enableContinuousBuffer(): void
338 {
339 parent::enableContinuousBuffer();
340 if ($this->mode_3cbc) {
341 $this->des[0]->enableContinuousBuffer();
342 $this->des[1]->enableContinuousBuffer();
343 $this->des[2]->enableContinuousBuffer();
344 }
345 }
346
347 /**
348 * Treat consecutive packets as if they are a discontinuous buffer.
349 *
350 * The default behavior.
351 *
352 * @see \phpseclib3\Crypt\Common\SymmetricKey::disableContinuousBuffer()
353 * @see self::enableContinuousBuffer()
354 */
355 public function disableContinuousBuffer(): void
356 {
357 parent::disableContinuousBuffer();
358 if ($this->mode_3cbc) {
359 $this->des[0]->disableContinuousBuffer();
360 $this->des[1]->disableContinuousBuffer();
361 $this->des[2]->disableContinuousBuffer();
362 }
363 }
364
365 /**
366 * Creates the key schedule
367 *
368 * @see \phpseclib3\Crypt\DES::setupKey()
369 * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey()
370 */
371 protected function setupKey(): void
372 {
373 switch (true) {
374 // if $key <= 64bits we configure our internal pure-php cipher engine
375 // to act as regular [1]DES, not as 3DES. mcrypt.so::tripledes does the same.
376 case strlen($this->key) <= 8:
377 $this->des_rounds = 1;
378 break;
379
380 // otherwise, if $key > 64bits, we configure our engine to work as 3DES.
381 default:
382 $this->des_rounds = 3;
383
384 // (only) if 3CBC is used we have, of course, to setup the $des[0-2] keys also separately.
385 if ($this->mode_3cbc) {
386 $this->des[0]->setupKey();
387 $this->des[1]->setupKey();
388 $this->des[2]->setupKey();
389
390 // because $des[0-2] will, now, do all the work we can return here
391 // not need unnecessary stress parent::setupKey() with our, now unused, $key.
392 return;
393 }
394 }
395 // setup our key
396 parent::setupKey();
397 }
398
399 /**
400 * Sets the internal crypt engine
401 *
402 * @see \phpseclib3\Crypt\Common\SymmetricKey::setPreferredEngine()
403 * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct()
404 */
405 public function setPreferredEngine(string $engine): void
406 {
407 if ($this->mode_3cbc) {
408 $this->des[0]->setPreferredEngine($engine);
409 $this->des[1]->setPreferredEngine($engine);
410 $this->des[2]->setPreferredEngine($engine);
411 }
412
413 parent::setPreferredEngine($engine);
414 }
415 }
416