Как правильно реализовать ввод, маскировку и безопасное хранение логинов и паролей в 1С:Предприятие 8.3

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

В этой статье мы подробно разберем, как спроектировать надежную, безопасную и удобную для пользователей форму авторизации. Мы рассмотрим механизмы маскировки ввода, алгоритмы хэширования, безопасное хранилище Библиотеки стандартных подсистем (БСП) и функционал автозаполнения логинов.

Проблема 1: Правильная маскировка пароля «звездочками» на управляемой форме

Часто начинающие разработчики связывают поле ввода пароля напрямую с реквизитом базы данных, в котором хранится хэш пароля. Это приводит к ситуации, описанной в Сообщении 6: платформа считывает хэш длиной, например, в 40 или 64 символа и маскирует его целиком. Пользователь видит огромное количество звездочек и думает, что произошла ошибка.

Для корректной реализации маскировки применим профессиональный подход:

  1. Создадим на форме авторизации/регистрации временный Реквизит формы (например, с именем ВведенныйПароль) с типом данных Строка.
  2. Вынесем этот реквизит на форму в виде поля ввода и в его свойствах установим флаг РежимПароля = Истина.
  3. Стандарт безопасности 1С: Если форма открывается для редактирования уже существующего пароля, никогда не передавайте реальный хэш или пароль с сервера на клиент. Вместо этого в процедуре ПриСозданииНаСервере заполните реквизит ВведенныйПароль искусственной строкой-маркером (например, системным GUID или фиксированной строкой "********").
  4. При сохранении формы проанализируйте значение: если пользователь не изменял маскировочную строку, значит, перезаписывать пароль в базе данных не нужно. Если значение изменилось — выполняем процедуру хэширования и записи нового значения.

Рассмотрим пример кода для инициализации и проверки изменения пароля на форме:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Инициализируем маску для существующего пользователя
    Если ЗначениеЗаполнено(Объект.Ссылка) Тогда
        // Записываем искусственный маркер, чтобы скрыть реальную длину пароля
        ВведенныйПароль = "********"; 
        ПарольИзменен = Ложь;
    Иначе
        ВведенныйПароль = "";
        ПарольИзменен = Истина;
    КонецЕсли;
    
КонецПроцедуры

&НаКлиенте
Процедура ВведенныйПарольПриИзменении(Элемент)
    ПарольИзменен = Истина;
КонецПроцедуры

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

Проблема 2: Реализация хэширования паролей «с солью» средствами 1С

Хранить пароли в открытом виде в справочниках (как упоминалось в Сообщении 8) категорически запрещено. Любой пользователь с правами администратора или программист, имеющий доступ к базе данных или консоли запросов, сможет скомпрометировать учетные данные пользователей. Пароли должны храниться исключительно в виде необратимых криптографических хэшей.

Для хэширования в платформе 1С:Предприятие 8.3 используется встроенный объект ХешированиеДанных. Забудьте про использование устаревшего и уязвимого алгоритма MD5 или SHA-1. Современный стандарт безопасности требует применения семейства алгоритмов SHA-256 или SHA-512. При необходимости можно воспользоваться практическими примерами реализации шифрования и хеширования штатными средствами платформы.

Чтобы защитить базу от взлома методом "радужных таблиц" (Rainbow Tables), мы обязательно должны использовать уникальную «соль» для каждого пользователя. Соль — это случайная строка, которая добавляется к паролю перед вычислением хэш-функции.

Проанализируем пример функции для генерации безопасного хэша на сервере:


&НаСервере
Функция ПолучитьХешПароля(Знач ПарольСтрокой, Знач Соль) Экспорт
    
    // Объединяем пароль и уникальную соль пользователя
    СтрокаДляХеширования = ПарольСтрокой + Соль;
    
    // Инициализируем объект шифрования по стандарту SHA-256
    Хешер = Новый ХешированиеДанных(ХешФункция.SHA256);
    Хешер.Добавить(СтрокаДляХеширования);
    
    // Получаем двоичные данные хэша и преобразуем их в шестнадцатеричную строку
    Возврат НРег(Строка(Хешер.ХешСумма));
    
КонецФункции

При регистрации пользователя сгенерируйте случайную уникальную соль (например, с помощью генератора GUID: Строка(Новый УникальныйИдентификатор)), сохраните соль в скрытом реквизите карточки пользователя, а в поле хэша запишите результат работы нашей функции. При авторизации считайте соль пользователя из базы, выполните хэширование введенного пароля с этой солью и сравните полученную строку с сохраненным хэшем.

Проблема 3: Хранение паролей сторонних систем (Безопасное хранилище БСП)

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

Для решения этой задачи в составе Библиотеки стандартных подсистем (БСП) предусмотрен механизм Безопасного хранилища данных. Данные в нем записываются в специальную защищенную системную таблицу СУБД в зашифрованном виде, а доступ к ним жестко регламентирован программным кодом.

Рассмотрим, как записать и прочитать пароль внешней системы с помощью методов БСП:


// Запись пароля в безопасное хранилище
Процедура СохранитьПарольИнтеграции(ВладелецУчетки, ПарольСтрокой) Экспорт
    
    УстановитьПривилегированныйРежим(Истина);
    
    // Записываем данные в привязке к конкретному объекту-владельцу
    ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(ВладелецУчетки, ПарольСтрокой, "ПарольАвторизации");
    
КонецПроцедуры

// Чтение пароля из безопасного хранилища
Функция ПолучитьПарольИнтеграции(ВладелецУчетки) Экспорт
    
    УстановитьПривилегированныйРежим(Истина);
    
    // Считываем пароль по ключу
    Возврат ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(ВладелецУчетки, "ПарольАвторизации");
    
КонецФункции

Обратите внимание на вызов метода УстановитьПривилегированныйРежим(Истина). Безопасное хранилище БСП спроектировано так, что доступ к данным из него может получить только доверенный серверный код, выполняемый в привилегированном режиме. Обычный пользователь через универсальные отчеты или консоли запросов не сможет извлечь эту информацию.

Проблема 4: Создание подсказки и выпадающего списка ранее вводившихся логинов

Для реализации удобного интерфейса (как упоминалось в Сообщении 5), когда система предлагает список ранее успешно использовавшихся логинов на данном рабочем месте, мы задействуем механизм локального кэширования настроек пользователя — ХранилищеОбщихНастроек.

Разберем по шагам алгоритм реализации этой задачи:

  1. На форме авторизации у поля ввода логина устанавливаем свойства РежимВыбораИзСписка = Истина и КнопкаВыпадающегоСписка = Истина.
  2. При открытии формы считываем массив логинов из ХранилищаОбщихНастроек и заполняем список выбора поля ввода.
  3. При успешном входе в систему добавляем введенный логин в массив истории (если его там еще нет) и сохраняем обновленный массив обратно в хранилище настроек.

Посмотрим на практический пример кода, реализующий этот функционал:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Считываем ранее сохраненный список логинов для текущего компьютера/пользователя
    КлючОбъекта = "ПараметрыАвторизации/ИсторияЛогинов";
    ИсторияЛогинов = ХранилищеОбщихНастроек.Загрузить(КлючОбъекта, "СписокЛогинов");
    
    Если ТипЗнч(ИсторияЛогинов) = Тип("Массив") Тогда
        // Заполняем список выбора элемента формы "Логин"
        Элементы.Логин.СписокВыбора.ЗагрузитьЗначения(ИсторияЛогинов);
    КонецЕсли;
    
КонецПроцедуры

&НаСервере
Процедура СохранитьЛогинВИстории(Знач ТекущийЛогин)
    
    КлючОбъекта = "ПараметрыАвторизации/ИсторияЛогинов";
    ИсторияЛогинов = ХранилищеОбщихНастроек.Загрузить(КлючОбъекта, "СписокЛогинов");
    
    Если ТипЗнч(ИсторияЛогинов) <> Тип("Массив") Тогда
        ИсторияЛогинов = Новый Массив;
    КонецЕсли;
    
    // Исключаем дублирование логина в списке
    Индекс = ИсторияЛогинов.Найти(ТекущийЛогин);
    Если Индекс <> Неопределено Тогда
        ИсторияЛогинов.Удалить(Индекс);
    КонецЕсли;
    
    // Добавляем новый логин в начало списка
    ИсторияЛогинов.Вставить(0, ТекущийЛогин);
    
    // Ограничиваем историю, например, последними 5 логинами
    Пока ИсторияЛогинов.Количество() > 5 Цикл
        ИсторияЛогинов.Удалить(ИсторияЛогинов.Количество() - 1);
    КонецЦикла;
    
    // Сохраняем обновленный список в локальное хранилище настроек
    ХранилищеОбщихНастроек.Сохранить(КлючОбъекта, "СписокЛогинов", ИсторияЛогинов);
    
КонецПроцедуры

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

Резюме и альтернативный вариант (Windows-авторизация)

Мы проанализировали полный стек технологий для построения безопасной подсистемы аутентификации на платформе 1С:Предприятие 8.3. Для развития этой задачи подойдет решение для внедрения двухфакторной аутентификации (2FA).

Тем не менее, если вашей задачей является обеспечение максимального уровня корпоративной безопасности и бесшовного входа пользователей в систему, настоятельно рекомендуем рассмотреть совет из Сообщения 22 — использование встроенной Windows-авторизации (Active Directory).

При использовании ОС-авторизации разработчику 1С вообще не требуется писать код для ввода, хранения и проверки паролей. Платформа 1С самостоятельно делегирует аутентификацию операционной системе при запуске клиента. Для настройки этого режима достаточно в карточке пользователя в Конфигураторе установить флаг "Аутентификация операционной системы" и указать имя пользователя домена Active Directory.

← На главную