Шифрование строк во встроенном языке 1С:Предприятия 8.3

· 9 мин

Содержание

Зашифровать строку в 1С 8.3 штатно можно двумя способами: через объект МенеджерКриптографии (нужен криптопровайдер и сертификат) или через архив ЗаписьZipФайла с паролем и методом МетодШифрованияZIP.AES256 — он работает без внешних программ. Base64 строку не шифрует, а только кодирует, а хеш SHA-256 подходит для паролей, но обратно его не прочитать.

Типичная задача: в справочнике «Настройки обмена» лежит пароль от FTP или токен маркетплейса открытым текстом. Любой, у кого есть права на чтение, видит его в форме или в выгрузке. Зашифровать такое значение можно в несколько строк кода, а вот выбор способа зависит от того, кто и где будет его расшифровывать.

Чем зашифровать строку в 1С: сравнение способов

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

СпособЧто даётНужно установитьОбратимоКогда брать
Base64СтрокаКодирование, не защитаНичегоДа, без ключаПередать двоичные данные текстом (JSON, XML)
ХешированиеДанных (SHA-256)Отпечаток строкиНичегоНетХранить пароли пользователей, сверять значения
ЗаписьZipФайла + AES-256Симметричное шифрование паролемНичегоДа, по паролюСекреты внутри базы, обмен между своими базами
МенеджерКриптографииШифрование на сертификат получателяКриптопровайдер, сертификатДа, закрытым ключомПередача данных контрагенту, требования ГОСТ
OpenSSL, внешняя компонентаЛюбой алгоритмПрограмма или компонента на сервереДаСовместимость с внешней системой по формату

Если внешняя система ждёт конкретный формат (например, AES-256-CBC с заданным вектором), ZIP-архив ей не подойдёт. Тогда остаются OpenSSL или внешняя компонента.

Как подготовить строку к шифрованию: двоичные данные и Base64

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

  1. 🔤 Строка → двоичные данные в явной кодировке.
  2. 🔐 Шифрование двоичных данных.
  3. 📦 Результат → строка Base64, чтобы сохранить его в реквизит или отправить в JSON.

Обратно — в зеркальном порядке.

// Строка в двоичные данные и обратно
ДД = ПолучитьДвоичныеДанныеИзСтроки("Пароль от FTP: Qw12!", КодировкаТекста.UTF8);
Строка = ПолучитьСтрокуИзДвоичныхДанных(ДД, КодировкаТекста.UTF8);

// Двоичные данные в Base64 и обратно
Текст64 = Base64Строка(ДД);
ДД2 = Base64Значение(Текст64);

Кодировку указывайте явно и одинаково с обеих сторон. Если зашифровать текст в UTF-8, а расшифрованные байты прочитать как Windows-1251, кириллица превратится в «кракозябры», хотя само шифрование отработало верно.

Строка Base64 может содержать переводы строк. Перед вставкой в URL или заголовок HTTP-запроса уберите их:

Текст64 = СтрЗаменить(СтрЗаменить(Base64Строка(ДД), Символы.ВК, ""), Символы.ПС, "");

Буфер двоичных данных и самописный XOR

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

XOR с коротким постоянным ключом вскрывается за минуты: достаточно знать кусок исходного текста. Годится только для маскировки от случайного взгляда, но не для защиты паролей и токенов.

Хеш вместо шифрования

Если строку не нужно читать обратно, а только сравнивать (пароль пользователя внешнего сайта, PIN), храните не шифр, а хеш с солью:

Соль = Строка(Новый УникальныйИдентификатор);
Хеш = Новый ХешированиеДанных(ХешФункция.SHA256);
Хеш.Добавить(ПолучитьДвоичныеДанныеИзСтроки(Соль + Пароль, КодировкаТекста.UTF8));
ХешСтрокой = ПолучитьHexСтрокуИзДвоичныхДанных(Хеш.ХешСумма);
// Сохраните Соль и ХешСтрокой; при проверке посчитайте хеш заново и сравните

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

Шифрование строки в 1С через МенеджерКриптографии

МенеджерКриптографии — объект платформы, который работает через установленный на компьютере криптопровайдер: КриптоПро CSP, ViPNet CSP или встроенный провайдер Windows. Шифрование асимметричное: данные шифруют на сертификат получателя, а расшифровать их может только владелец закрытого ключа.

Этот способ выбирают, когда строку нужно передать контрагенту или когда регламент требует ГОСТ-алгоритмов.

Что подготовить

  • 🧩 Криптопровайдер, установленный там, где выполняется код. Для серверного кода — на сервере 1С.
  • 📜 Сертификат получателя в хранилище того пользователя Windows, от имени которого работает код. Для сервера это учётная запись службы рабочих процессов, а не ваша.
  • 🔑 Для расшифровки — закрытый ключ и пароль к нему.

Пример кода

Имя и тип модуля ниже даны для КриптоПро CSP с ГОСТ Р 34.10-2012. Для другого провайдера подставьте его имя и тип: их показывает сама программа-провайдер.

&НаСервере
Функция ЗашифроватьСтрокуНаСертификат(Текст, ОтпечатокHex)

	Менеджер = Новый МенеджерКриптографии(
		"Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider", "", 80);

	Хранилище = Менеджер.ПолучитьХранилищеСертификатов(
		ТипХранилищаСертификатовКриптографии.ПерсональныеСертификаты);
	Сертификат = Хранилище.НайтиПоОтпечатку(ПолучитьДвоичныеДанныеИзHexСтроки(ОтпечатокHex));

	Если Сертификат = Неопределено Тогда
		ВызватьИсключение "Сертификат с отпечатком " + ОтпечатокHex + " не найден";
	КонецЕсли;

	Исходные = ПолучитьДвоичныеДанныеИзСтроки(Текст, КодировкаТекста.UTF8);
	Зашифрованные = Менеджер.Зашифровать(Исходные, Сертификат);

	Возврат Base64Строка(Зашифрованные);

КонецФункции

&НаСервере
Функция РасшифроватьСтроку(Шифр64, ПарольКлюча)

	Менеджер = Новый МенеджерКриптографии(
		"Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider", "", 80);
	Менеджер.ПарольДоступаКЗакрытомуКлючу = ПарольКлюча;

	Расшифрованные = Менеджер.Расшифровать(Base64Значение(Шифр64));
	Возврат ПолучитьСтрокуИзДвоичныхДанных(Расшифрованные, КодировкаТекста.UTF8);

КонецФункции

Вторым параметром Зашифровать можно передать массив сертификатов. Тогда расшифровать сообщение сможет каждый из получателей.

На клиенте в конфигурациях без модальности синхронные методы криптографии вызывают ошибку. Там используют асинхронные варианты: ИнициализироватьАсинх, ЗашифроватьАсинх, РасшифроватьАсинх с Ждать. В типовых конфигурациях на БСП удобнее вызывать общие модули подсистемы «Электронная подпись»: они уже учитывают клиент, сервер и разных провайдеров.

Симметричное шифрование строки паролем без внешних программ

Если ключ один и известен только вашей базе, проще всего упаковать строку в ZIP-архив с шифрованием AES-256. Объект ЗаписьZipФайла есть в платформе, ничего ставить не нужно. Соль и служебные параметры алгоритма формат ZIP хранит внутри архива сам.

&НаСервере
Функция ЗашифроватьСтрокуПаролем(Текст, Пароль)

	ИмяТекста = ПолучитьИмяВременногоФайла("txt");
	ИмяАрхива = ПолучитьИмяВременногоФайла("zip");

	ПолучитьДвоичныеДанныеИзСтроки(Текст, КодировкаТекста.UTF8).Записать(ИмяТекста);

	Архив = Новый ЗаписьZipФайла(ИмяАрхива, Пароль, ,
		МетодСжатияZIP.Сжатие, УровеньСжатияZIP.Оптимальный, МетодШифрованияZIP.AES256);
	Архив.Добавить(ИмяТекста, РежимСохраненияПутейZIP.НеСохранятьПути);
	Архив.Записать();

	Результат = Base64Строка(Новый ДвоичныеДанные(ИмяАрхива));

	УдалитьФайлы(ИмяТекста);
	УдалитьФайлы(ИмяАрхива);
	Возврат Результат;

КонецФункции

&НаСервере
Функция РасшифроватьСтрокуПаролем(Шифр64, Пароль)

	ИмяАрхива = ПолучитьИмяВременногоФайла("zip");
	Каталог = КаталогВременныхФайлов() + Строка(Новый УникальныйИдентификатор);
	Base64Значение(Шифр64).Записать(ИмяАрхива);

	Чтение = Новый ЧтениеZipФайла(ИмяАрхива, Пароль);
	ИмяЭлемента = Чтение.Элементы[0].Имя;
	Чтение.ИзвлечьВсе(Каталог);
	Чтение.Закрыть();

	ИмяФайла = Каталог + ПолучитьРазделительПути() + ИмяЭлемента;
	Результат = ПолучитьСтрокуИзДвоичныхДанных(Новый ДвоичныеДанные(ИмяФайла), КодировкаТекста.UTF8);

	УдалитьФайлы(ИмяАрхива);
	УдалитьФайлы(Каталог);
	Возврат Результат;

КонецФункции

Код выполняйте на сервере. Временные файлы с открытым текстом живут доли секунды, но всё же ложатся на диск, поэтому удаляйте их сразу, как в примере.

Метод МетодШифрованияZIP.Zip20 (старое шифрование ZIP) не используйте: он слабый. Выбирайте AES256.

Минус способа: результат — это ZIP-архив, а не «чистый» шифротекст AES. Другая программа прочитает его только как архив с паролем, например 7-Zip.

Шифрование через OpenSSL и внешние компоненты

Когда партнёр присылает требование вида «AES-256-CBC, ключ из пароля через PBKDF2, результат в Base64», встроенных средств мало. Варианта два.

Вызов OpenSSL из 1С

OpenSSL ставится на сервер 1С (в Linux он обычно уже есть). Код записывает строку во временный файл, вызывает утилиту через ЗапуститьПриложение и читает результат:

&НаСервере
Функция ЗашифроватьЧерезOpenSSL(Текст, ФайлКлюча)

	Вход = ПолучитьИмяВременногоФайла("txt");
	Выход = ПолучитьИмяВременногоФайла("b64");
	ПолучитьДвоичныеДанныеИзСтроки(Текст, КодировкаТекста.UTF8).Записать(Вход);

	Команда = СтрШаблон(
		"openssl enc -aes-256-cbc -pbkdf2 -iter 100000 -salt -a -in ""%1"" -out ""%2"" -pass file:""%3""",
		Вход, Выход, ФайлКлюча);

	КодВозврата = 0;
	ЗапуститьПриложение(Команда, , Истина, КодВозврата);
	УдалитьФайлы(Вход);

	Если КодВозврата <> 0 Тогда
		ВызватьИсключение "OpenSSL завершился с кодом " + Формат(КодВозврата, "ЧН=0; ЧГ=0");
	КонецЕсли;

	Результат = ПолучитьСтрокуИзДвоичныхДанных(Новый ДвоичныеДанные(Выход), КодировкаТекста.UTF8);
	УдалитьФайлы(Выход);
	Возврат СокрЛП(Результат);

КонецФункции

Расшифровка — та же команда с ключом -d. Пароль передаётся через файл (-pass file:), а не аргументом командной строки: аргументы видны в списке процессов сервера.

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

Внешняя компонента

Второй путь — внешняя компонента по технологии Native API (на C++), которая вызывает криптобиблиотеку напрямую. Её подключают через ПодключитьВнешнююКомпоненту (или асинхронный вариант на клиенте) и создают объект через Новый("AddIn.ИмяКомпоненты.ИмяОбъекта"). Плюсы: нет временных файлов и запуска процессов. Минусы: компоненту надо собрать или купить и поддерживать под все разрядности сервера.

COM-объект CAPICOM из старых примеров в интернете давно не поддерживается Microsoft. На новых серверах на него не рассчитывайте.

Где хранить ключ, пароль и вектор инициализации

Шифрование ровно настолько надёжно, насколько хорошо спрятан ключ. Самая частая ошибка — пароль прямо в общем модуле: Пароль = "Secret2024". Код конфигурации видит каждый, кто откроет Конфигуратор или выгрузит базу в .dt.

Варианты получше, от простого к надёжному:

  • 🗄️ Безопасное хранилище БСП. В типовых конфигурациях есть функции ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище и ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища. Данные лежат в отдельном регистре, доступ к нему есть только в привилегированном режиме. Это не шифрование, но рядовой пользователь значение не увидит.
  • 📁 Файл на сервере вне каталога базы. Права на файл — только у учётной записи службы 1С. В базу он не попадает, в копию .dt тоже.
  • 🔑 Закрытый ключ в контейнере криптопровайдера. Для МенеджерКриптографии: ключ не покидает контейнер, а пароль к нему можно не хранить вовсе, если контейнер настроен без пароля для служебной учётной записи.

Про вектор инициализации (IV) и соль:

  1. Вектор должен быть случайным и новым для каждого шифрования. Одинаковый IV при одном ключе выдаёт одинаковые начала текстов.
  2. Вектор не секретен. Его хранят рядом с шифротекстом, обычно в его начале.
  3. В ZIP AES-256 и в OpenSSL с параметром -salt соль генерируется автоматически и записывается в результат, отдельно хранить её не нужно.
  4. Если внешняя система задаёт IV явно (-iv в OpenSSL вместе с ключом -K), уточните у неё, как она передаёт его вместе с данными.

Сделайте копию ключа и проверьте расшифровку на копии базы до того, как зашифруете рабочие данные. Потерянный пароль от AES-архива или удалённый закрытый ключ означает, что данные не вернуть никак.

Обработка ошибок при шифровании и расшифровке

Любой вызов шифрования оборачивайте в Попытка ... Исключение. Неверный пароль, отсутствующий сертификат или повреждённый Base64 вызывают исключение, и без обработки пользователь увидит окно ошибки с технической трассировкой.

Попытка
	Токен = РасшифроватьСтрокуПаролем(ЗашифрованныйТокен, Пароль);
Исключение
	Инфо = ИнформацияОбОшибке();
	ЗаписьЖурналаРегистрации("Шифрование.Расшифровка", УровеньЖурналаРегистрации.Ошибка, , ,
		ПодробноеПредставлениеОшибки(Инфо));
	ВызватьИсключение "Не удалось расшифровать токен. Проверьте пароль в настройках обмена.";
КонецПопытки;

В журнал регистрации пишите подробности, а пользователю — понятное сообщение. Расшифрованное значение и пароль в журнал не записывайте никогда.

Диагностика: выберите симптом

Отдельная ловушка — длина реквизита. Шифротекст в Base64 длиннее исходной строки: ZIP-архив с короткой строкой занимает пару сотен байт, а Base64 добавляет к размеру ещё треть. Реквизит строки длиной 100 символов обрежет результат, и расшифровать его уже не получится. Для хранения задавайте строку неограниченной длины или тип ХранилищеЗначения.

Частые вопросы

Можно ли зашифровать строку в 1С без КриптоПро?
Да. Объект ЗаписьZipФайла с методом МетодШифрованияZIP.AES256 шифрует данные паролем средствами самой платформы, без криптопровайдера и внешних программ.
Base64 — это шифрование?
Нет. Base64 только переводит байты в текст. Любой раскодирует его без ключа обычной функцией Base64Значение или онлайн-сервисом.
Как зашифровать пароль пользователя, чтобы потом проверять его?
Не шифруйте, а храните хеш SHA-256 с солью через ХешированиеДанных. При входе считайте хеш введённого пароля с той же солью и сравнивайте строки.
Будет ли шифрование работать в файловой базе?
Да. Все приведённые способы работают и в файловом, и в клиент-серверном варианте. В файловом режиме «сервер» — это процесс клиента, поэтому криптопровайдер и сертификат нужны на компьютере пользователя.
Зашифрованная строка из одной базы расшифруется в другой?
Да, если совпадают пароль (для ZIP и OpenSSL) или в другой базе доступен закрытый ключ сертификата получателя (для МенеджерКриптографии). Привязки к конкретной базе у шифротекста нет.