Encryption::getAdapter()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
/**
4
 * Platine Security
5
 *
6
 * Platine Security provides a complete security system with encryption, hash support
7
 *
8
 * This content is released under the MIT License (MIT)
9
 *
10
 * Copyright (c) 2020 Platine Security
11
 * Copyright (c) 2013 G4Code
12
 *
13
 * Permission is hereby granted, free of charge, to any person obtaining a copy
14
 * of this software and associated documentation files (the "Software"), to deal
15
 * in the Software without restriction, including without limitation the rights
16
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
 * copies of the Software, and to permit persons to whom the Software is
18
 * furnished to do so, subject to the following conditions:
19
 *
20
 * The above copyright notice and this permission notice shall be included in all
21
 * copies or substantial portions of the Software.
22
 *
23
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
 * SOFTWARE.
30
 */
31
32
/**
33
 *  @file Lang.php
34
 *
35
 *  The translator main class
36
 *
37
 *  @package    Platine\Security
38
 *  @author Platine Developers Team
39
 *  @copyright  Copyright (c) 2020
40
 *  @license    http://opensource.org/licenses/MIT  MIT License
41
 *  @link   https://www.platine-php.com
42
 *  @version 1.0.0
43
 *  @filesource
44
 */
45
46
declare(strict_types=1);
47
48
namespace Platine\Security;
49
50
use InvalidArgumentException;
51
use Platine\Security\Encryption\AdapterInterface;
52
use Platine\Security\Encryption\Cipher;
53
use Platine\Security\Encryption\OpenSSL;
54
use Platine\Security\Exception\EncryptionException;
55
56
/**
57
 * @class Lang
58
 * @package Platine\Security
59
 */
60
class Encryption
61
{
62
    /**
63
     * The adapter instance
64
     * @var AdapterInterface
65
     */
66
    protected AdapterInterface $adapter;
67
68
    /**
69
     * The encryption/decryption secret key
70
     * @var string
71
     */
72
    protected string $secret = '';
73
74
    /**
75
     * The hashed secret
76
     * @var string
77
     */
78
    protected string $hashedSecret = '';
79
80
    /**
81
     * The initialization vector
82
     * @var int
83
     */
84
    protected int $initVectorSize;
85
86
    /**
87
     * Create new instance
88
     * @param AdapterInterface|null $adapter
89
     */
90
    public function __construct(?AdapterInterface $adapter = null)
91
    {
92
        $this->adapter = $adapter ?? new OpenSSL([]);
93
        $this->initVectorSize = $this->adapter->getIVSize();
94
    }
95
96
    /**
97
     * Return the adapter instance
98
     * @return AdapterInterface
99
     */
100
    public function getAdapter(): AdapterInterface
101
    {
102
        return $this->adapter;
103
    }
104
105
    /**
106
     * Set secret
107
     * @param string $secret
108
     * @return $this
109
     */
110
    public function setSecret(string $secret): self
111
    {
112
        if (empty(trim($secret))) {
113
            throw new InvalidArgumentException('The secret can not be empty');
114
        }
115
        $this->secret = $secret;
116
        $this->hashedSecret = md5($secret);
117
118
        return $this;
119
    }
120
121
    /**
122
     * Encode the given data
123
     * @param string $data
124
     * @return string
125
     */
126
    public function encode(string $data): string
127
    {
128
        return $this->encryptData($data);
129
    }
130
131
    /**
132
     * Decode the given encrypted data
133
     * @param string $data
134
     * @return string
135
     */
136
    public function decode(string $data): string
137
    {
138
        return $this->decryptData($data);
139
    }
140
141
142
    /**
143
     * Encrypt the data
144
     * @param string $data
145
     * @return string
146
     */
147
    protected function encryptData(string $data): string
148
    {
149
        $initVector = $this->adapter->createIV($this->initVectorSize);
150
        $encrypted = $initVector . $this->adapter->encrypt(
151
            $this->hashedSecret,
152
            $data,
153
            $initVector
154
        );
155
156
        $cipher = new Cipher($encrypted, $this->hashedSecret);
157
158
        return $this->base64UrlEncode(
159
            $cipher->addCipherNoise()
160
        );
161
    }
162
163
    /**
164
     * Decrypt the encrypted data
165
     * @param string $data
166
     * @return string
167
     */
168
    protected function decryptData(string $data): string
169
    {
170
        $encrypted = $this->base64UrlDecode($data);
171
172
        $cipher = new Cipher($encrypted, $this->hashedSecret);
173
174
        $cleanEncrypted = $cipher->removeCipherNoise();
175
176
        if ($this->initVectorSize > strlen($cleanEncrypted)) {
177
            throw new EncryptionException('The encrypted data to decode is invalid');
178
        }
179
180
        $initVector = substr($cleanEncrypted, 0, $this->initVectorSize);
181
182
        $dataEncrypted = substr($cleanEncrypted, $this->initVectorSize);
183
184
        return rtrim(
185
            $this->adapter->decrypt(
186
                $this->hashedSecret,
187
                $dataEncrypted,
188
                $initVector
189
            ),
190
            "\0"
191
        );
192
    }
193
194
    /**
195
     * Base64 URL encode
196
     * @param string $value
197
     * @return string
198
     */
199
    protected function base64UrlEncode(string $value): string
200
    {
201
        return rtrim(
202
            strtr(
203
                base64_encode($value),
204
                '+/',
205
                '-_'
206
            ),
207
            '='
208
        );
209
    }
210
211
    /**
212
     * Base64 URL decode
213
     * @param string $value
214
     * @return string
215
     */
216
    protected function base64UrlDecode(string $value): string
217
    {
218
        return base64_decode(str_pad(
219
            strtr($value, '-_', '+/'),
220
            strlen($value) % 4,
221
            '=',
222
            STR_PAD_RIGHT
223
        ));
224
    }
225
}
226