Completed
Push — master ( db7ab9...a6011d )
by Anton
04:58
created

Encrypter::withKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 1
eloc 4
nc 1
nop 1
1
<?php
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
namespace Spiral\Encrypter;
9
10
use Spiral\Core\Container\InjectableInterface;
11
use Spiral\Encrypter\Exceptions\DecryptException;
12
use Spiral\Encrypter\Exceptions\EncrypterException;
13
use Spiral\Encrypter\Exceptions\EncryptException;
14
15
/**
16
 * Default implementation of spiral encrypter. Sugary implementation at top of defuse/php-encryption
17
 *
18
 * @see https://github.com/defuse/php-encryption
19
 */
20
class Encrypter implements EncrypterInterface, InjectableInterface
21
{
22
    /**
23
     * Injection is dedicated to outer class since Encrypter is pretty simple.
24
     */
25
    const INJECTOR = EncrypterManager::class;
26
27
    /**
28
     * @var string
29
     */
30
    private $key = '';
31
32
    /**
33
     * Encrypter constructor.
34
     *
35
     * @param string $key
36
     */
37
    public function __construct($key)
38
    {
39
        $this->key = $key;
40
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45
    public function withKey($key)
46
    {
47
        $encrypter = clone $this;
48
        $encrypter->key = (string)$key;
49
50
        return $encrypter;
51
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56
    public function getKey()
57
    {
58
        return $this->key;
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     *
64
     * @todo double check
65
     * @param bool $passWeak Do not throw an exception if result is "weak". Not recommended.
66
     */
67
    public function random($length, $passWeak = false)
68
    {
69
        if ($length < 1) {
70
            throw new EncrypterException("Random string length should be at least 1 byte long.");
71
        }
72
73
        $result = openssl_random_pseudo_bytes($length, $cryptoStrong);
74
        if ($result === false) {
75
            throw new EncrypterException(
76
                "Unable to generate pseudo-random string with {$length} length."
77
            );
78
        }
79
80
        if (!$passWeak && !(bool)$cryptoStrong) {
81
            throw new EncrypterException("Weak random result received.");
82
        }
83
84
        return $result;
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     *
90
     * Data encoded using json_encode method, only supported formats are allowed!
91
     */
92
    public function encrypt($data)
93
    {
94
        $packed = json_encode($data);
95
96
        try {
97
            return \Crypto::Encrypt($packed, $this->key);
98
        } catch (\CannotPerformOperationException $e) {
99
            throw new EncryptException($e->getMessage(), $e->getCode(), $e);
100
        } catch (\CryptoTestFailedException $e) {
101
            throw new EncrypterException($e->getMessage(), $e->getCode(), $e);
102
        }
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     *
108
     * json_decode with assoc flag set to true
109
     */
110
    public function decrypt($payload)
111
    {
112
        try {
113
            $result = \Crypto::Decrypt($payload, $this->key);
114
115
            return json_decode($result, true);
116
        } catch (\InvalidCiphertextException $e) {
117
            throw new DecryptException($e->getMessage(), $e->getCode(), $e);
118
        } catch (\CannotPerformOperationException $e) {
119
            throw new DecryptException($e->getMessage(), $e->getCode(), $e);
120
        } catch (\CryptoTestFailedException $e) {
121
            throw new EncrypterException($e->getMessage(), $e->getCode(), $e);
122
        }
123
    }
124
}
125