Шифрование строк во встроенном языке 1С:Предприятия 8.3
Содержание
Зашифровать строку в 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
Все механизмы шифрования в платформе работают не со строкой, а с типом ДвоичныеДанные. Поэтому цепочка всегда одна:
- 🔤 Строка → двоичные данные в явной кодировке.
- 🔐 Шифрование двоичных данных.
- 📦 Результат → строка 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) и соль:
- Вектор должен быть случайным и новым для каждого шифрования. Одинаковый IV при одном ключе выдаёт одинаковые начала текстов.
- Вектор не секретен. Его хранят рядом с шифротекстом, обычно в его начале.
- В ZIP AES-256 и в OpenSSL с параметром
-saltсоль генерируется автоматически и записывается в результат, отдельно хранить её не нужно. - Если внешняя система задаёт IV явно (
-ivв OpenSSL вместе с ключом-K), уточните у неё, как она передаёт его вместе с данными.
Сделайте копию ключа и проверьте расшифровку на копии базы до того, как зашифруете рабочие данные. Потерянный пароль от AES-архива или удалённый закрытый ключ означает, что данные не вернуть никак.
Обработка ошибок при шифровании и расшифровке
Любой вызов шифрования оборачивайте в Попытка ... Исключение. Неверный пароль, отсутствующий сертификат или повреждённый Base64 вызывают исключение, и без обработки пользователь увидит окно ошибки с технической трассировкой.
Попытка
Токен = РасшифроватьСтрокуПаролем(ЗашифрованныйТокен, Пароль);
Исключение
Инфо = ИнформацияОбОшибке();
ЗаписьЖурналаРегистрации("Шифрование.Расшифровка", УровеньЖурналаРегистрации.Ошибка, , ,
ПодробноеПредставлениеОшибки(Инфо));
ВызватьИсключение "Не удалось расшифровать токен. Проверьте пароль в настройках обмена.";
КонецПопытки;
В журнал регистрации пишите подробности, а пользователю — понятное сообщение. Расшифрованное значение и пароль в журнал не записывайте никогда.
Отдельная ловушка — длина реквизита. Шифротекст в Base64 длиннее исходной строки: ZIP-архив с короткой строкой занимает пару сотен байт, а Base64 добавляет к размеру ещё треть. Реквизит строки длиной 100 символов обрежет результат, и расшифровать его уже не получится. Для хранения задавайте строку неограниченной длины или тип ХранилищеЗначения.
Частые вопросы
Можно ли зашифровать строку в 1С без КриптоПро?
ЗаписьZipФайла с методом МетодШифрованияZIP.AES256 шифрует данные паролем средствами самой платформы, без криптопровайдера и внешних программ.Base64 — это шифрование?
Base64Значение или онлайн-сервисом.Как зашифровать пароль пользователя, чтобы потом проверять его?
ХешированиеДанных. При входе считайте хеш введённого пароля с той же солью и сравнивайте строки.