-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDatabaseEncryptor.php
More file actions
139 lines (122 loc) · 4.85 KB
/
Copy pathDatabaseEncryptor.php
File metadata and controls
139 lines (122 loc) · 4.85 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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<?php
declare(strict_types=1);
namespace CryptoFramework\Database;
use CryptoFramework\Exceptions\CryptoException;
use CryptoFramework\Interfaces\SymmetricCryptoInterface;
use CryptoFramework\Symmetric\AES256GCM;
use CryptoFramework\Utils\RandomGenerator;
/**
* Classe para criptografia de dados em banco de dados
*/
final class DatabaseEncryptor
{
/**
* @param SymmetricCryptoInterface $cipher Cifra para criptografia
* @param RandomGenerator $randomGenerator Gerador de números aleatórios
*/
public function __construct(
private readonly SymmetricCryptoInterface $cipher = new AES256GCM(),
private readonly RandomGenerator $randomGenerator = new RandomGenerator()
) {
}
/**
* Criptografa um valor para armazenamento em banco de dados
*
* @param mixed $value Valor a ser criptografado
* @param string $key Chave de criptografia
* @param string|null $context Contexto para autenticação adicional
* @return string Valor criptografado (formato: base64)
* @throws CryptoException
*/
public function encryptValue(mixed $value, string $key, ?string $context = null): string
{
try {
// Serializar o valor
$serialized = serialize($value);
// Criptografar o valor serializado
return $this->cipher->encrypt($serialized, $key, $context);
} catch (\Exception $e) {
throw new CryptoException("Erro ao criptografar valor: " . $e->getMessage(), previous: $e);
}
}
/**
* Descriptografa um valor armazenado em banco de dados
*
* @param string $encryptedValue Valor criptografado
* @param string $key Chave de criptografia
* @param string|null $context Contexto para autenticação adicional
* @return mixed Valor descriptografado
* @throws CryptoException
*/
public function decryptValue(string $encryptedValue, string $key, ?string $context = null): mixed
{
try {
// Descriptografar o valor
$serialized = $this->cipher->decrypt($encryptedValue, $key, $context);
// Desserializar o valor
$value = unserialize($serialized);
if ($value === false && $serialized !== 'b:0;') {
throw new CryptoException("Falha ao desserializar valor");
}
return $value;
} catch (\Exception $e) {
throw new CryptoException("Erro ao descriptografar valor: " . $e->getMessage(), previous: $e);
}
}
/**
* Criptografa um array de valores para armazenamento em banco de dados
*
* @param array<string, mixed> $values Array de valores a serem criptografados
* @param string $key Chave de criptografia
* @param array<string> $encryptFields Campos a serem criptografados
* @param string|null $context Contexto para autenticação adicional
* @return array<string, mixed> Array com valores criptografados
* @throws CryptoException
*/
public function encryptArray(array $values, string $key, array $encryptFields, ?string $context = null): array
{
$result = $values;
foreach ($encryptFields as $field) {
if (isset($values[$field])) {
$result[$field] = $this->encryptValue($values[$field], $key, $context);
}
}
return $result;
}
/**
* Descriptografa um array de valores armazenados em banco de dados
*
* @param array<string, mixed> $values Array de valores criptografados
* @param string $key Chave de criptografia
* @param array<string> $encryptFields Campos criptografados
* @param string|null $context Contexto para autenticação adicional
* @return array<string, mixed> Array com valores descriptografados
* @throws CryptoException
*/
public function decryptArray(array $values, string $key, array $encryptFields, ?string $context = null): array
{
$result = $values;
foreach ($encryptFields as $field) {
if (isset($values[$field]) && is_string($values[$field])) {
$result[$field] = $this->decryptValue($values[$field], $key, $context);
}
}
return $result;
}
/**
* Gera uma chave de criptografia para um modelo específico
*
* @param string $modelName Nome do modelo
* @param string $masterKey Chave mestra
* @return string Chave de criptografia
* @throws CryptoException
*/
public function generateModelKey(string $modelName, string $masterKey): string
{
try {
return hash_hmac('sha256', $modelName, $masterKey, true);
} catch (\Exception $e) {
throw new CryptoException("Erro ao gerar chave para modelo: " . $e->getMessage(), previous: $e);
}
}
}