*/ use HasFactory; use HasPdnEncryption; use SoftDeletes; protected $table = 'personal_data'; protected $fillable = [ 'owner_id', 'subject_pseudonym', 'last_name', 'first_name', 'middle_name', 'birth_date', 'passport', 'snils', 'phone', ]; /** * Шифруемые поля ПДн (мера ЗНИ). * * @var array */ protected array $encrypted = [ 'last_name', 'first_name', 'middle_name', 'birth_date', 'passport', 'snils', 'phone', ]; protected static function booted(): void { // Контроль целостности (ОЦЛ.2): пересчёт контрольной суммы при сохранении. static::saving(function (PersonalData $model): void { $model->checksum = $model->calculateChecksum(); }); } /** * @return BelongsTo */ public function owner(): BelongsTo { return $this->belongsTo(User::class, 'owner_id'); } /** * HMAC по расшифрованному содержимому ПДн-полей — для проверки целостности. */ public function calculateChecksum(): string { $payload = []; foreach ($this->encrypted as $attribute) { $payload[$attribute] = $this->getAttribute($attribute); } $key = (string) config('audit.hmac_key'); $key = str_starts_with($key, 'base64:') ? (string) base64_decode(substr($key, 7), true) : $key; return hash_hmac('sha256', (string) json_encode($payload, JSON_UNESCAPED_UNICODE), $key); } /** * Проверка целостности записи (ОЦЛ.2). */ public function integrityValid(): bool { return $this->checksum !== null && hash_equals($this->checksum, $this->calculateChecksum()); } }