first commit
This commit is contained in:
74
app/Models/Concerns/HasPdnEncryption.php
Normal file
74
app/Models/Concerns/HasPdnEncryption.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Concerns;
|
||||
|
||||
use App\Services\Crypto\PdnCipher;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Прозрачное шифрование полей персональных данных на уровне приложения.
|
||||
*
|
||||
* Мера ФСТЭК: ЗНИ (защита носителей), ОЦЛ.2 (контроль целостности данных).
|
||||
*
|
||||
* Использование в модели:
|
||||
*
|
||||
* use HasPdnEncryption;
|
||||
* protected array $encrypted = ['last_name', 'passport', 'snils'];
|
||||
*
|
||||
* Шифрование выполняется выбранным драйвером (config/security.php → encryption),
|
||||
* что позволяет заменить AES на сертифицированное СКЗИ (ГОСТ) без правки моделей.
|
||||
*/
|
||||
trait HasPdnEncryption
|
||||
{
|
||||
public function setAttribute($key, $value)
|
||||
{
|
||||
if ($this->isPdnEncrypted($key) && $value !== null) {
|
||||
$value = $this->pdnCipher()->encrypt((string) $value);
|
||||
}
|
||||
|
||||
return parent::setAttribute($key, $value);
|
||||
}
|
||||
|
||||
public function getAttribute($key)
|
||||
{
|
||||
$value = parent::getAttribute($key);
|
||||
|
||||
if ($this->isPdnEncrypted($key) && $value !== null && is_string($value)) {
|
||||
try {
|
||||
return $this->pdnCipher()->decrypt($value);
|
||||
} catch (Throwable $e) {
|
||||
// Нарушение целостности/невозможность расшифровки — инцидент (ИНЦ.1).
|
||||
Log::channel(config('audit.siem.channel', 'stack'))->error('pdn.decrypt_failed', [
|
||||
'model' => static::class,
|
||||
'attribute' => $key,
|
||||
'id' => $this->getKey(),
|
||||
]);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Список зашифрованных атрибутов модели.
|
||||
*
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public function encryptedAttributes(): array
|
||||
{
|
||||
return $this->encrypted;
|
||||
}
|
||||
|
||||
protected function isPdnEncrypted(string $key): bool
|
||||
{
|
||||
return in_array($key, $this->encryptedAttributes(), true);
|
||||
}
|
||||
|
||||
protected function pdnCipher(): PdnCipher
|
||||
{
|
||||
return app(PdnCipher::class);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user