# Шифрование значений атрибутов

Шифрование значений атрибутов предназначено для хранения чувствительных строковых данных в зашифрованном виде. Механизм можно использовать для паролей, токенов и других учетных данных, которые необходимы системе для обращения к сторонним ресурсам и должны храниться в базе данных в зашифрованном виде.

Механизм применяется к обычным строковым атрибутам класса, JSON-атрибутам и объектным характеристикам, а также универсальным характеристикам.

Для атрибута с настроенным шифрованием значение автоматически шифруется при записи через предусмотренные для него методы доступа. Для обычных атрибутов шифрование и расшифровка выполняются сгенерированными setter и getter DPI/ROP. Для JSON-атрибутов, объектных и универсальных характеристик используются соответствующие API. Реляционные запросы и прямой доступ к базе данных автоматическую расшифровку не выполняют.

Значения шифруются с возможностью последующей автоматической расшифровки, например для использования учетных данных при обращении к внешнему сервису.

По умолчанию автоматическое шифрование атрибутов выключено.

## Настройка общего механизма

Для работы автоматического шифрования должна быть включена настройка **Включено шифрование атрибутов** (`bEnabledFieldEncryption`).

Путь: `Настройка системы > Настройки и сервисы > Настройка модулей системы > Общие настройки модулей > btk > Безопасность и аутентификация`.

Ранее сохраненные незашифрованные значения автоматически не преобразуются. После включения настройки они шифруются при следующей записи через предусмотренные для соответствующего атрибута методы доступа.

Признак шифрования отдельного атрибута применяется вместе с общей настройкой. При выключенной `bEnabledFieldEncryption` автоматическое шифрование при записи не выполняется, даже если для атрибута установлен признак шифрования.

## Атрибуты класса

После включения общей настройки откройте атрибут класса и установите признак **Зашифрованный атрибут**.

Путь: `Сущности > Классы > нужный класс > атрибуты`.

Признак **Зашифрованный атрибут** доступен для базовых атрибутов с типами данных:

- `Varchar`;
- `Text`;
- `Clob`.

```{note}
Для атрибута `gid` механизм шифрования значений не применяется.
```

Для атрибутов, задаваемых в ODM, шифрование можно включить параметром `isEncrypted="true"`:

```xml
<attr name="sPassword" attribute-type="Varchar" caption="Пароль" type="basic" isEncrypted="true"/>
```

Для зашифрованного атрибута при кодогенерации формируются методы доступа, которые выполняют шифрование при записи и расшифровку при чтении.

Для JSON-атрибутов и объектных характеристик шифрование и расшифровка выполняются через `JObjectAttrApi`.

Для поддерживаемых строковых зашифрованных атрибутов по умолчанию используется редактор `editPassword`, который скрывает значение в интерфейсе. Редактор используется для отображения и не выполняет шифрование.

Перед снятием признака шифрования с атрибута учитывайте представление уже сохраненных значений и при необходимости преобразуйте их. Для физического атрибута признак шифрования определяет использование механизма расшифровки в сгенерированном getter.

## Универсальные характеристики

После включения общей настройки откройте нужную универсальную характеристику и установите признак **Зашифрованный атрибут**.

Путь: `Сущности > Универсальные характеристики`.

Признак шифрования доступен для универсальной характеристики со следующими параметрами:

- базовый тип;
- тип данных `Varchar`;
- одно значение;
- обычное, неинтервальное значение;
- постоянное значение без временной зависимости.

При изменении параметров характеристики доступность признака шифрования пересчитывается автоматически.

При записи значения универсальной характеристики через `JObjectAttrApi.setUniCharValue` выполняется автоматическое шифрование. При чтении через `Btk_UniversalCharacteristicApi.getValue` выполняется расшифровка.

## Использование в прикладном коде

Для чтения и записи зашифрованных значений используйте методы доступа соответствующего типа атрибута:

- для обычных атрибутов — сгенерированные getter и setter DPI/ROP;
- для JSON-атрибутов и объектных характеристик — `JObjectAttrApi`;
- для универсальных характеристик — `JObjectAttrApi.setUniCharValue` для записи и `Btk_UniversalCharacteristicApi.getValue` для чтения.

При чтении атрибута через сгенерированный getter выполняется автоматическая расшифровка. Реляционные запросы и прямой доступ к базе данных автоматическую расшифровку не выполняют.

Для прямого шифрования и расшифровки строковых значений используется `ru.bitec.app.btk.security.Btk_EncryptedFieldPkg`.

Пример:

```scala
import ru.bitec.app.gtk.Lang.*
import ru.bitec.app.btk.security.Btk_EncryptedFieldPkg

val encrypted = Btk_EncryptedFieldPkg().encrypt("data".ns)
val decrypted = Btk_EncryptedFieldPkg().decrypt(encrypted)
```

Значения `encrypted` и `decrypted` имеют тип `NString`.

Основные операции `Btk_EncryptedFieldPkg`:

| Операция | Назначение |
| --- | --- |
| `encrypt` | Шифрует непустое значение, если оно еще не имеет признака зашифрованного значения. Настройку `bEnabledFieldEncryption` не проверяет |
| `encryptIfNeeded` | Вызывает `encrypt` при включенной настройке `btk.bEnabledFieldEncryption` |
| `decrypt` | Расшифровывает значение поддерживаемого формата. Значение другого формата возвращает без изменений |
| `isEncrypted` | Проверяет наличие технического префикса зашифрованного значения |

Для атрибутов с настроенным автоматическим шифрованием используйте указанные выше методы доступа к значениям.