-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEncryptor.php
More file actions
110 lines (98 loc) · 4.02 KB
/
Encryptor.php
File metadata and controls
110 lines (98 loc) · 4.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
<?php
declare(strict_types=1);
namespace Phphleb\Encryptor;
use InvalidArgumentException;
/**
* Performs encryption and decryption of string values (previously encrypted in this way).
* Suitable for AES encryption methods.
*
* Осуществляет шифрование и расшифровку строковых значений (ранее зашифрованных этим способом).
* Подходит для методов шифрования AES.
*/
final readonly class Encryptor
{
/**
* These parameters must be the same for encryption and decryption of the same value type.
*
* Эти параметры должны быть одинаковы для шифрования и расшифровки одного типа значения.
*
* @param string $key - passphrase.
* - кодовая фраза.
*
* @param string $cipherMethod - encryption method (AES).
* - метод шифрования (AES).
*
* @param int $ivLength - the length of the initializing vector must correspond
* to the size of the encryption method block.
*
* - длина инициализирующего вектора, должна соответствовать
* размерам блока шифровального метода.
*/
public function __construct(
#[\SensitiveParameter] private string $key,
#[\SensitiveParameter] private string $cipherMethod = 'aes-256-cbc',
#[\SensitiveParameter] private int $ivLength = 16,
)
{
if (empty($this->key)) {
throw new InvalidArgumentException("Salt cannot be empty");
}
if (empty($this->cipherMethod)) {
throw new InvalidArgumentException("Cipher method cannot be empty");
}
if (empty($this->ivLength)) {
throw new InvalidArgumentException("IV length cannot be empty");
}
}
/**
* Encrypts a string of arbitrary length, returning ciphertext.
*
* Шифрует строку произвольной длины, возвращая зашифрованный текст.
*
* @throws EncryptorException
*/
public function encrypt(#[\SensitiveParameter] string $plaintext): string
{
if ($plaintext === '') {
return '';
}
$iv = openssl_random_pseudo_bytes($this->ivLength);
try {
$ciphertext = openssl_encrypt($plaintext, $this->cipherMethod, $this->key, OPENSSL_RAW_DATA, $iv);
} catch (\Exception $e) {
throw new EncryptorException($e->getMessage(), $e->getCode(), $e);
}
return base64_encode($iv . $ciphertext);
}
/**
* Decrypts text encrypted by the encrypt() method, returning the decrypted string.
*
* Расшифровывает текст, зашифрованный методом encrypt(), возвращая расшифрованную строку.
*
* @throws EncryptorException|EncryptorFailedException
*/
public function decrypt(string $ciphertext): string
{
if ($ciphertext === '') {
return '';
}
$decoded = base64_decode($ciphertext, true);
if (!$decoded) {
throw new EncryptorFailedException("Decryption failed: invalid data");
}
$iv = substr($decoded, 0, $this->ivLength);
$encryptedData = substr($decoded, $this->ivLength);
if ($encryptedData === '') {
throw new EncryptorFailedException("Decryption failed");
}
try {
$plaintext = openssl_decrypt($encryptedData, $this->cipherMethod, $this->key, OPENSSL_RAW_DATA, $iv);
} catch (\Exception $e) {
throw new EncryptorException($e->getMessage(), $e->getCode(), $e);
}
if ($plaintext === false) {
throw new EncryptorFailedException("Decryption failed");
}
return $plaintext;
}
}