# Настройка хеширования паролей операторов (password_hashers)

Параметр `password_hashers` позволяет задать список поддерживаемых алгоритмов хеширования паролей операторов и управлять миграцией на новый алгоритм без принудительного сброса всех паролей.

Механика рассчитана на сценарий «прозрачной миграции»: сервер продолжает принимать старые хэши, а после успешного входа оператора пароль автоматически перехешируется по «новому» алгоритму и будет сохранён в базе.

## Где настраивается

Настройки читаются из конфигураций Webim Server:

  * `main.ini` и файлы в `/etc/webim/main.ini.d/*.ini`

  * `main.json` и файлы в `/etc/webim/main.json.d/*.json`

Используемые параметры:

  * `password_salt` (в `main.ini`) — «наследуемая» соль для **md5 по умолчанию**, если список хешеров не задан.

  * `password_hashers` (в `main.json`) — список конфигураций хеширования.

!!! Note "Важно про merge main.json"
    В ряде компонентов (включая **Admin Backend**) JSON-настройки из `main.json` и `main.json.d/*.json` объединяются, при этом **списки конкатенируются**.  
    Поэтому `password_hashers` рекомендуется задавать **ровно в одном файле** и **одним списком**, чтобы не получить дубликаты/«двойные» конфигурации.

## Параметр password_hashers

`password_hashers` — это список объектов, порядок элементов в списке **имеет значение**:

  * **первый** элемент используется для проверки хэшей **без префикса `{id}`** (наследуемые значения);

  * **последний** элемент считается «актуальным» и используется для хеширования новых паролей и перехеширования при успешном входе.

### Формат элемента списка

| Поле   | Тип    | Обязательно | Описание                                                                                                                                   |
|--------|--------|-------------|--------------------------------------------------------------------------------------------------------------------------------------------|
| `id`   | string | да          | Идентификатор конфигурации хеширования. Используется как префикс в БД: `{id}<hash>`.                                                       |
| `algo` | string | да          | Алгоритм хеширования.                                                                                                                      |
| `salt` | string | да          | Соль. Для `md5`/`sha256` используется как префикс: `salt + password`. Для `argon2` не применяется (рекомендуется оставить пустой строкой). |

### Требования к id

  * `id` должен быть **уникальным** в пределах списка.

  * Рекомендуемый набор символов: `A–Z`, `a–z`, `0–9`, `_`, `-`.

  * Скобки `{}` в `id` указывать не нужно — они добавляются системой при сохранении хэша.

### Поддерживаемые значения algo

  * `md5`

  * `sha256`

  * `argon2`

!!! Note "Совместимость по компонентам"
    Перед включением `argon2` убедитесь, что в вашем контуре аутентификация операторов выполняется компонентами, которые его поддерживают. Если есть компоненты, которые проверяют пароль через стандартные `md5/sha256` (без argon2-проверки), вход операторов может перестать работать.  
    Универсальный вариант для миграции — `md5 → sha256`.

### Требования к salt

  * Для `md5`/`sha256` хэш вычисляется от строки `salt + password`.

  * Рекомендуется использовать **ASCII**-строку (чтобы исключить проблемы с кодировками между компонентами).

  * Если соль не нужна — задайте пустую строку: `"salt": ""`.

## Формат хранения хэша в БД

Пароль оператора хранится в таблице `chatoperator`, поле `password` (в hosted-окружениях часто используется схема `webim_hosted_meta`).

Возможные форматы значения:

  * без идентификатора (наследуемый формат):

    * `82e8fe7e1194b8ce42addb5374ccb047`

  * с идентификатором хешера:

    * `{md5-default}82e8fe7e1194b8ce42addb5374ccb047`

    * `{new-default}62d045c783245ca1ce9e98b21f67825005110adca59a8f36e5dab731cc4b422c`

## Как работает миграция и перехеширование

  1. При входе система определяет, какой хешер применить:

    * если пароль в БД имеет префикс `{id}`, используется конфигурация с этим `id`;

    * если префикса нет — используется **первый** элемент списка `password_hashers`.

  1. Если вход успешен и текущий хешер **не является актуальным** (обычно не последний в списке), пароль будет **перехеширован** по актуальному алгоритму и сохранён обратно в БД (с префиксом `{id}` для актуального хешера).

## Пример: переход с md5 на sha256

Ниже — практический сценарий миграции по схеме «сохраняем поддержку md5, добавляем sha256 как актуальный».

### 1. Предусловие: текущие пароли — md5

Пример md5:

  * `pazzword` → `82e8fe7e1194b8ce42addb5374ccb047`

Перед применением конфигурации рекомендуется убедиться, что текущие значения действительно соответствуют md5 (32 hex-символа) и не содержат префиксов `{id}`.

PostgreSQL (пример):

```
SELECT operatorid, email, password
FROM webim_hosted_meta.chatoperator
WHERE password !~ '^[0-9a-fA-F]{32}$';
```

MySQL (пример):

```
SELECT operatorid, email, password
FROM webim_hosted_meta.chatoperator
WHERE password NOT REGEXP '^[0-9a-fA-F]{32}$';
```


Если запрос возвращает строки — разберите причины до миграции (часть паролей уже могла быть в другом формате).

### 2. Определите текущую соль md5 (password_salt)

Соль берётся из `/etc/webim/main.ini` и/или файлов в `/etc/webim/main.ini.d/*.ini` (в hosted-контуре часто встречается `/etc/webim/main.ini.d/hosted-main.ini`).

Пример проверки:

```
grep -R "^[[:space:]]password_salt" /etc/webim/main.ini /etc/webim/main.ini.d/.ini
```


Соль может быть пустой:

  * `password_salt = ""`

### 3. Добавьте список хешеров в main.json

Создайте/измените файл `/etc/webim/main.json.d/main.json` и задайте список `password_hashers`.

Пример: соль была и осталась пустой:

```
{
"partner_settings": {
"default": {
"domain": ""
}
},
"password_hashers": [
{"algo": "md5", "salt": "", "id": "md5-default"},
{"algo": "sha256", "salt": "", "id": "new-default"}
]
}
```


Если у вас уже задан `password_salt`, то для md5 укажите **ту же соль**, чтобы старые пароли продолжили проверяться корректно:

```
"password_hashers": [
{"algo": "md5", "salt": "<текущая_соль_password_salt>", "id": "md5-default"},
{"algo": "sha256", "salt": "<новая_соль>", "id": "new-default"}
]
```


!!! Note "Если у вас версия, где параметр называется password_hashing"
    В некоторых версиях параметр в `main.json` мог называться `password_hashing`. Если в вашем релизе `password_hashers` не применяется, используйте аналогичную структуру под ключом `password_hashing`.

### 4. Перезапустите сервисы, читающие конфигурацию

После сохранения изменений перезапустите сервисы и проверьте статус:

```
systemctl restart webim-tornado
systemctl restart webim-admin-backend

systemctl status webim-admin-backend
systemctl status webim-tornado
```


### 5. Проверьте перехеширование после входа

После первого успешного логина оператором его пароль будет сохранён по актуальному алгоритму (`sha256`) и, как правило, с префиксом `{new-default}`.

Пример sha256:

  * `pazzword` → `62d045c783245ca1ce9e98b21f67825005110adca59a8f36e5dab731cc4b422c`

  * в БД: `{new-default}62d045c...`

Проверка «остались ли md5 без префикса» (PostgreSQL пример):

```
SELECT count(*)
FROM webim_hosted_meta.chatoperator
WHERE password ~ '^[0-9a-fA-F]{32}$';
```


## Рекомендации эксплуатации

  * Не удаляйте md5-хешер из списка, пока не убедитесь, что все пароли мигрировали на новый формат (или пока не выполните принудительную смену пароля всем операторам).

  * Не меняйте `id` уже используемого хешера: иначе система не сможет сопоставить `{id}` в БД с конфигурацией.

  * Для миграции между `md5` и `sha256` используйте разные `id` (например, `md5-default` и `new-default`).

  * Соль храните как секрет (как минимум ограничьте доступ к файлам `/etc/webim/main.ini*` и `/etc/webim/main.json*`).

---

Источник: https://webim.ru/kb/devops/password-hashers.html
