Как написать RSA на встроенном языке 1С без COM и .NET

07.08.26

Разработка - Защита ПО и шифрование

Платёжный шлюз принимает номер карты только зашифрованным по RSA, а почти все реализации RSA в 1С зовут .NET через COM - и это молча ломается на Linux-сервере, в тонком клиенте и на голой Windows без regasm. Разбираю, как написать RSA целиком на встроенном языке: как хранить большие числа лимбами по основанию миллион, откуда берётся деление Кнута и square-and-multiply, почему первая версия считала 25 секунд и как это ускорилось в 8 раз. С проверкой байт в байт против внешнего эталона на больших числах.

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

Вопрос один: как в 1С сделать это самое шифрование RSA публичным ключом.

 

Как это обычно делают в 1С - и почему это ломается

Если поискать по площадке, почти все ответы одинаковые: взять из .NET класс RSACryptoServiceProvider через COM.

КриптоПровайдер = Новый COMОбъект("System.Security.Cryptography.RSACryptoServiceProvider");
КриптоПровайдер.FromXmlString(ПубличныйКлючXML);
Шифр = КриптоПровайдер.Encrypt(Данные, Ложь);

Работает. Ровно до того момента, когда ты выносишь этот код на другую машину. Потому что .NET-классы по умолчанию не зарегистрированы для COM, и на голой системе первый же Новый COMОбъект(...) отвечает:

0x80040154: Класс не зарегистрирован

Лечится это регистрацией сборки через regasm - то есть административной вознёй на каждой машине. А на Linux-сервере и в тонком клиенте COM нет вообще, и лечить нечего. Для кода, который ты отдаёшь другим, это плохая опора: у половины он просто не заведётся.

Захотелось иначе. Написать RSA целиком на встроенном языке 1С, без единой внешней компоненты. Чтобы тот же код шёл где угодно.

 

В чём подвох: в 1С нет больших чисел

RSA - это, по сути, одна формула. Шифрование:

c = m^e mod n

Расшифровка:

m = c^d mod n

Где m - это сообщение как число, (n, e) - публичный ключ, (n, d) - приватный. Возведение в степень по модулю, и всё.

Загвоздка в том, что n для боевого ключа - это число на 600 с лишним десятичных цифр. А тип Число в 1С столько не держит: он десятичный, с ограниченной точностью, и на больших значениях просто теряет разряды. Нативного «длинного целого», как BigInteger в .NET или встроенные большие числа в Python, в 1С нет.

Значит, большие числа и арифметику над ними придётся собрать самому.

 

Кирпичик первый: как хранить большое число

Число хранится массивом «лимбов» - кусочков по основанию 106, младший разряд первым. То есть число 123456789012 - это массив из двух лимбов: [789012, 123456]. Основание 106 выбрано не случайно: произведение двух лимбов меньше 1012, а это влезает в тип Число без потери точности, значит умножать лимбы можно напрямую.

Дальше поверх этого массива - обычная школьная арифметика:

  • сравнение - сначала по длине, потом полимбно от старшего;
  • сложение - в столбик с переносом;
  • вычитание - в столбик с заёмом.

Ничего хитрого, это первые страницы любого учебника. Единственная 1С-специфика, на которой легко обжечься: цикл Для ... По ... Цикл считает только вверх. Проход от старшего разряда к младшему через Для Индекс = Длина - 1 По 0 молча не выполнится - его надо писать через Пока. Ошибки не будет, просто число соберётся неправильно, и ищи потом, почему шифртекст не тот.

 

Кирпичик второй: умножение и деление

Умножение больших чисел - тоже столбик: каждый лимб первого на каждый лимб второго, с накоплением переносов. O(лимбов2), для наших размеров быстро.

А вот деление больших чисел - самое неприятное место. Оно нужно не само по себе, а ради остатка: в формуле RSA везде mod n, то есть после каждого умножения надо взять остаток от деления на n. Наивное деление через многократное вычитание слишком медленное, поэтому здесь работает классический алгоритм Кнута D: нормализация делителя, поразрядная оценка частного и коррекция, когда оценка промахнулась. Это самый длинный кусок кода во всей обработке, но он стандартный и отлаженный десятилетиями.

 

Кирпичик третий: возведение в степень по модулю

Теперь собственно RSA. Возводить в степень наивно, умножая m само на себя e раз, нельзя: e - тоже огромное число, столько итераций никто не дождётся. Работает square-and-multiply: идём по битам показателя степени, на каждом бите возводим текущий результат в квадрат, а где бит единичный - домножаем на основание. И то, и другое - по модулю n. Битов у степени сотни, а не астрономическое число, поэтому всё считается за разумное время.

Результат = Единица();
Для Каждого Бит Из БитыСтепени Цикл       // биты показателя, старший первым
    Результат = ОстатокОтДеления(Умножить(Результат, Результат), Модуль);
    Если Бит = 1 Тогда
        Результат = ОстатокОтДеления(Умножить(Результат, Основа), Модуль);
    КонецЕсли;
КонецЦикла;

Вот и весь RSA. Шифрование - это modexp(m, e, n). Расшифровка - modexp(c, d, n). Одна и та же функция, разные показатели.

 

История про скорость: 25 секунд и как их убрать

Первая рабочая версия считала модульное умножение хитрым приёмом «сдвиг-и-сложение», который вообще обходится без деления - только сложения и вычитания. Красиво, но медленно: расшифровка 160-битного ключа занимала 25 секунд. Причина - у этого приёма сложность O(бит2), и на каждый бит идёт полноценная операция над большим числом.

Замена на «честное умножение плюс деление Кнута» дала ускорение примерно в 8 раз: то же самое стало считаться за пару секунд. Разница в том, что теперь на один шаг возведения в степень приходится одно умножение и одно деление, а не сотни сложений.

Отсюда и выбор размера демо-ключа. Время растёт квадратично: 256 бит - около 3 секунд, а 512 бит - уже под 25. Для демонстрации принципа взят ключ 256 бит: он маленький с точки зрения криптостойкости, но расшифровка укладывается в пару секунд, и всё видно глазами. В бою, разумеется, минимум 2048 - там расшифровку делает шлюз на нативном движке, а не интерпретируемый BSL.

 

Главное: как убедиться, что оно правда работает

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

Поэтому проверка тройная.

Классический учебный вектор. Самый маленький осмысленный RSA: n=3233, e=17, d=413. Число 65 обязано зашифроваться в 2790 и расшифроваться обратно в 65. Наш modexp даёт ровно это.

Внешний эталон, байт в байт. Тот же самый шифртекст для того же ключа независимо посчитан реализацией на арифметике больших чисел (BigInteger). И совпал с тем, что выдал 1С, символ в символ в base64, по всем входам - и по номеру карты, и по кириллице, и по адресу почты. Это и есть настоящее доказательство: наш нативный RSA даёт не «какой-то свой» результат, а ровно тот, что даёт стандартная арифметика. Значит, шлюз такой шифртекст поймёт.

Круговой прогон. И уже поверх этого - обычная проверка «зашифровали публичным, расшифровали приватным, получили исходное» на разных строках.

 

Что видно в демо

Чтобы это не осталось теорией, всё собрано в маленькую обработку с одной кнопкой. Вводишь тестовый номер карты (или оставляешь пустым - подставится пример), жмёшь «Показать принцип», и через пару секунд поля заполняются по шагам.

Публичный ключ показан прямо на форме: модуль N на 77 десятичных цифр и экспонента 65537. Номер карты 4111111111111111 превращается в шифртекст aUzrnamZKH9hk+ATKnVeMpduP2Q1KjNEoVCZ5C+svs8= - и это ровно та строка, которую на том же ключе выдаёт внешний эталон на больших числах. Ниже поле «расшифровано приватным ключом» показывает исходный номер обратно: круг замкнулся, ничего по дороге не потерялось. И отдельной строкой - подпись SHA256 и готовое тело запроса, в котором сырого номера карты уже нет, только шифртекст.

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

 

Почему именно основание миллион

Про выбор основания 106 стоит сказать отдельно, потому что это тонкое место. Соблазн - хранить число в базе 2 (битами) или в базе 10 (по одной десятичной цифре на элемент). Оба варианта рабочие, но медленные: элементов получается слишком много, а операций над ними - тем более.

Хочется класть в один элемент побольше, но тут упираешься в точность типа Число. При умножении двух элементов их произведение должно остаться точным целым. Если брать основание 109, произведение доходит до 1018 - а это уже за границей, где Число начинает округлять, и арифметика тихо поедет. Основание 106 держит произведение в пределах 1012 плюс переносы, это заведомо точно. Баланс: крупные куски ради скорости, но не настолько крупные, чтобы потерять точность. Мелочь, а если ошибиться - вся криптография развалится незаметно.

 

Вторая половина: подпись запроса

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

подпись = SHA256(base64(тело_запроса) + секретный_ключ_проекта);

И вот эта половина в 1С нативна изначально: SHA256 даёт платформенный объект ХешированиеДанных, base64 - встроенные функции. Никакого COM. Одна тонкость: ХешированиеДанных доступен на сервере, а не на клиенте, так что подпись считается серверным вызовом. Зато работает и на Linux-сервере тоже.

 

Что в итоге получилось

Небольшая обработка, которая на одной кнопке показывает весь цикл: берёт номер карты, шифрует его публичным ключом, тут же расшифровывает приватным (как это сделал бы шлюз), собирает тело запроса и подписывает его. Всё - на чистом встроенном языке, без COM, .NET и внешних компонент. Тот же код запускается в толстом клиенте, в тонком и на Linux-сервере.

Это учебная демонстрация принципа, а не боевая криптобиблиотека: ключ 256 бит для скорости, без PKCS#1-паддинга, публичный ключ встроен. Но математика настоящая и сверена с эталоном, а не сымитирована.

 

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

Можно ли этим шифровать в проде? В таком виде - нет, и это честно написано в карточке. Демо-ключ 256 бит и отсутствие PKCS#1-паддинга - сознательные упрощения ради наглядности. Но сам движок (длинная арифметика, деление Кнута, modexp) - настоящий; на ключе 2048 бит он тоже верен, просто расшифровка на интерпретируемом BSL будет долгой. В реальной интеграции расшифровку делает шлюз, а тебе нужно только шифрование публичным ключом - оно с малой экспонентой 65537 быстрое даже на больших числах.

Зачем вообще нативно, если есть COM? Ради переносимости. Код, который зовёт .NET через COM, привязан к Windows с зарегистрированной сборкой. Как только появляется Linux-сервер, тонкий или веб-клиент - он молча перестаёт работать. Нативный BSL идёт везде одинаково, и это ровно тот случай, когда «медленнее, но везде» лучше, чем «быстро, но только здесь».

Почему подпись отдельно от шифрования? Это две разные задачи. Шифрование прячет чувствительное поле (номер карты) от всех, кроме шлюза. Подпись же не прячет ничего - она подтверждает, что запрос собрал именно ты и его не подменили. Поэтому шифруется только карта, а подписывается всё тело целиком.

Почему в подписи сначала base64, потом ключ? Так устроен контракт у многих шлюзов: подписывается не сырое тело, а его base64-представление, склеенное с секретом проекта, и от этого берётся SHA256. Конкретный порядок склейки задаёт шлюз в своей документации; здесь показан типовой вариант.

Готовая обработка лежит отдельной публикацией, можно скачать и покрутить. Работает на любой конфигурации от 8.3.14, ставить ничего не надо, код открыт.

Нативный RSA в 1С: демо шифрования карты для платёжного шлюза

 

Другие мои инструменты

Тот же подход «криптография на чистом BSL, без внешних компонент» - в Аудите паролей СУБД: там AES-128-CBC на встроенном языке читает пароль пользователя СУБД из файла кластера 1CV8Clst.lst, чтобы проверить собственную инфраструктуру.

Из соседнего - линейка «1С и нейросети»: Выгрузка структуры метаданных отдаёт модели устройство базы, а Анонимизатор выгрузки позволяет безопасно дать ей сами данные. И линейка диагностики производительности: Карта объёмов, Чек-ап СУБД, Трансформатор SQL, Оптимизатор временных таблиц.

Вступайте в нашу телеграмм-группу Инфостарт

RSA 1С шифрование в 1С криптография на встроенном языке BSL платёжный шлюз длинная арифметика деление Кнута square-and-multiply modexp без COM без .NET SHA256 base64

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

Защита ПО и шифрование Программист 1С:Предприятие 8 Бесплатно (free)

Платформенная защита модулей конфигураций, внешних обработок и расширений 1С легко «взламывается» общедоступными декомпиляторами, а использование СЛК (Система лицензирования и защиты конфигураций) часто избыточно из-за необходимости установки дополнительного ПО и покупки ключей. Рассмотрим использование методики защиты логики через обфускацию байт-кода, а именно частный случай использования метода, который позволит привязать решение к «железу» пользователя без использования внешних компонент и онлайн-активации.

19.02.2026    3115    1c-izh    9    

9

Защита ПО и шифрование Программист Бухгалтер Пользователь 1С:Предприятие 8 Россия Абонемент ($m)

Обработка для подписи с помощью сертификата (ЭЦП) произвольных файлов, средствами платформы 1С.

5 стартмани

19.06.2025    2183    3    krundel    2    

0

Защита ПО и шифрование 1С:Предприятие 8 Абонемент ($m)

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

1 стартмани

03.06.2025    2478    user1195929    13    

4

Защита ПО и шифрование Программист 1С:Предприятие 8 Абонемент ($m)

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

1 стартмани

09.04.2025    4064    user1195929    6    

4

Защита ПО и шифрование Программист 1С:Предприятие 8 Россия Абонемент ($m)

Обработки, в которых реализованы алгоритмы шифрования ГОСТ 34.10-2012, RSA-1024, AES-256-GCM, XChacha20-poly1305. Реализация нативно на чистом 1С без COM-объектов и внешних компонент.

1 стартмани

17.03.2025    5298    55    alexyur    10    

7

Защита ПО и шифрование Программист 1С:Предприятие 8 1С:Управление торговлей 11 Абонемент ($m)

Небольшой пример - "лайф-хак" по установке собственного пароля на отчет или обработку, не втягивая в это RLS.

3 стартмани

06.03.2025    3809    7    aximo    23    

13

Защита ПО и шифрование Программист 1С:Предприятие 8 Бесплатно (free)

В статье приведен простой способ защиты кода внешней обработки от несанкционированного доступа (если это необходимо).

30.12.2024    11194    artemusII    26    

10

Защита ПО и шифрование Программист 1С:Предприятие 8 1С:Бухгалтерия 3.0 Абонемент ($m)

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

1 стартмани

09.02.2023    5282    15    aximo    5    

2
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Трактор 1288 07.08.26 16:53 Сейчас в теме
Что видно в демо

Где демо?
Нашёл. Это отдельная публикация. Похоже кто-то ИИ настроил на засирание Инфостарта публикациями.
Для отправки сообщения требуется регистрация/авторизация