– Каталог готовых решений для 1С”

- Каталог готовых решений для 1С" Электронная цифровая подпись

001. криптография и цифровая подпись rsa-sha256 на платформе 1с

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

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

Когда мне была поставлена задача реализовать подписание ЭЦП по алгоритму SHA256-rcaпаддинг pkcs1 с ключами 2048 я решил, что сделаю все в 3 строки кода:

Хэш=Новый ХешированиеДанных(ХешФункция.SHA256);
Хэш.Добавить("Тра ля ля");
Сообщить(Хэш.ХешСумма);

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

Но где же RSA? А ключи? Короче ждал меня облом.

Можно задействовать внешний криптопровайдер, но это стоит денег, да и сервер на котором все должно работать находится в Америке и там же админится, дадут ли устанавливать лишний софт – большой вопрос.

Поиски в интернете готового решения не дали, пришлось садиться в студию и кодить компоненту net.

Для запуска компоненты используется C компонента NETLoader, скачанная с инфостарта.

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

Все процедуры выполняются в один поток и на больших данных могут подвисать. Но на практике мне такое не встретилось.

В этом видео показано как все работает:

Для тестирования методов компоненты (без учета особенностей работы платформы 1с) реализовано Windows приложение (см в архиве WindowsFormsTest1.exe). Компонента адаптирована для работы как с платформой 1с, так и как самостоятельного решения для использования в других задачах. Требования – net.3.5. Тестирование производилось на платформе 8.3.12 на управляемом интерфейсе в контексте сервера. Компонента реализует:
подписание по алгоритму SHA-256 с шифрованием хеша подписи по алгоритму RCA PKCS1 при помощи, ключей размером 2048
проверку (валидацию) подписи
шифрование и дешифровку данных по алгоритму
RSA PKCS1 про помощи ключей, размером 2048
В 1с компоненту можно задействовать при помощи служебной компоненты netloader.dll (встроена в фреймворк).

Создание ключей шифрования
Назначение: создает новые ключи шифрования
Имя метода: GetKeysInXML(string randomstring)
Параметры: randomstring (произвольная строка, обязательный параметр) – не используется, остался в наследие от первой версии компоненты.
Возвращаемое значение: Истина или Ложь.
Приватный и публичный ключ можно получить, обратившись к свойствам компоненты publicKey и privateKey
Значения ключей представлены в формате XML, поля которого содержат двоичные данные в формате base64

Формирование цифровой подписи
Назначение: формирует цифровую подпись переданных данных
Имя метода: SignData(string DataToSign, string privateKey)
Параметры: DataToSign (строка) – данные, которые необходимо подписать; privateKey (строка) – приватный ключ в формате XML.
Возвращаемое значение: Истина или Ложь
Значение подписи можно получить, обратившись к свойству компоненты Base64SignedHash
Значение – это двоичные данные в формате base64

Проверка цифровой подписи
Назначение: возвращает результат проверки цифровой подписи
Имя метода: VerifySignature(string DataToSign, string signature, string publicKey)
Параметры: DataToSign (строка) – данные, которые необходимо подписать; signature (строка) – цифровая подпись в формате base64; privateKey (строка) – приватный ключ в формате XML.
Возвращаемое значение: Истина или Ложь
Если подпись прошла проверку – возвращает Истина

Шифрование данных
Назначение: шифровка данных
Имя метода: EncryptData(string originalMessage, string publicKey)
Параметры:  originalMessage (строка) – данные, которые необходимо зашифровать; publicKey (строка) – публичный ключ в формате XML.
Возвращаемое значение: Истина или Ложь
Результат шифрования можно прочитать из свойства encripteddata

Читайте также:  Квалифицированная электронная подпись — Тинькофф Помощь

Дешифрование данных
Назначение: дешифровка данных
Имя метода: DecryptData(string originalMessage, string privateKey)
Параметры:  originalMessage (строка) – данные, которые необходимо расшифровать; privateKey (строка) – приватный ключ в формате XML. Возвращаемое значение: Истина или Ложь
Возвращаемое значение: Истина или Ложь
Результат шифрования можно прочитать из свойства decripteddata;

Обработка ошибок
Если методы компоненты возвращают Ложь, возможно, в передаваемых параметрах допущены ошибки. Получить описание последней ошибки можно обратившись к свойству компоненты lasterror (строка)

Все публикации — все для 1с

Категория
Бухгалтерский учет (31996)
   Учет доходов и расходов (427)
   Внешнеэкономическая деятельность (ВЭД) (165)
   Банковские операции (1508)
   Бюджетный учет (601)
   Взаиморасчеты (2022)
   Займы, кредит, лизинг (136)
   Зарплата (6718)
   Кадровый учет (2518)
   Кассовые операции (1277)
   Оптовая торговля (7350)
   Печатные формы (9524)
   Производство готовой продукции (работ, услуг) (2965)
   Регламентированный учет и отчетность (835)
   Розничная торговля (3692)
   Склад и ТМЦ (5704)
   Учет ОС и НМА (956)
   Учет рабочего времени (747)
Управленческий учет (3493)
   СRM (526)
   Документооборот и делопроизводство (893)
   Консолидация данных (28)
   Управление услугами и сервисом (330)
   Управление персоналом (HRM) (50)
   Бюджетирование и планирование (377)
   ServiceDesk, HelpDesk (14)
   Task Manager (60)
   Управление знаниями Knowledge Base (14)
   Ценообразование, анализ цен (1301)
Пользовательские инструменты (19319)
   Сервисы ИТС (36)
   Инструкции пользователю (340)
   Игры (376)
   Адаптация типовых решений (449)
   Анализ учета (1589)
   Загрузка и выгрузка в Excel (1782)
   Закрытие периода (668)
   Корректировка данных (452)
   Менеджеры внешних отчетов (84)
   Монитор заказов (207)
   Обмен с интернет-банком (914)
   Оборотно-сальдовая ведомость, Анализ счета (477)
   Обработка документов (7792)
   Обработка справочников (2914)
   Пакетная печать (454)
   Поздравления (82)
   Поиск данных (538)
   Прайсы (782)
   Рабочее место (699)
   Универсальные обработки (1843)
   Финансовые (292)
   Разное (185)
Приемы и методы разработки (8672)
   БСП (Библиотека стандартных подсистем) (187)
   Идеи и тренды в разработке (50)
   Инструментарий разработчика (2861)
   Мобильная разработка (285)
   DevOps и автоматизация разработки (52)
   EDT (28)
   Infostart ERP community (23)
   OneScript (57)
   Групповая разработка (Git, хранилище) (66)
   Запросы (325)
   Защита ПО и шифрование (119)
   Локализация решений (9)
   Математика и алгоритмы (398)
   Механизмы платформы 1С (482)
   Механизмы типовых конфигураций (195)
   Практика программирования (724)
   Работа с интерфейсом (1406)
   Разработка внешних компонент (519)
   Рефакторинг и качество кода (76)
   СКД (302)
   Тестирование QA (60)
   Универсальные функции (819)
   Языки и среды (30)
Администрирование БД (3534)
   Инструменты администратора БД (1242)
   Администрирование СУБД (137)
   HighLoad оптимизация (332)
   Архивирование (backup) (277)
   Журнал регистрации (305)
   Обновление 1С (83)
   Свертка базы (207)
   Статистика базы данных (260)
   Технологический журнал (42)
   Чистка данных (813)
Системное администрирование (1151)
   Администрирование веб-серверов (43)
   Linux (28)
   Информационная безопасность (629)
   Мониторинг (35)
   Облачные сервисы, хостинг (33)
   Пароли (34)
   Роли и права (302)
   Сервера (17)
   Сети (12)
   Удаленное управление (16)
Интеграция и обмен данными (8153)
   Email рассылки (472)
   POS терминал (37)
   SMS рассылки (141)
   WEB-интеграция (1808)
   Боты (127)
   Весы (140)
   Внешние источники данных (1184)
   ККМ (439)
   Обмен между базами 1C (2477)
   Периферийные устройства (49)
   Ридер магнитных карт (13)
   Сканер штрих-кода (221)
   Телефония, SIP (77)
   Терминал сбора данных (117)
   Файловые протоколы обмена (TXT, XML, DBF), FTP (1776)
   Эквайринг (33)
Управление (2050)
   Анализ и проектирование ИТ-систем (344)
   Управление ИТ-подразделением (44)
   Управление командой (30)
   Управление проектом (439)
   Мотивация, лидерство и личная эффективность (179)
   Внедрение ИТ-системы (207)
   Инфостарт (125)
   О жизни (514)
   Подготовка к аттестации (232)

Читайте также:  Как установить ЭЦП на компьютер пошагово, с чего начать

Отрасль
1С:Франчайзи, автоматизация бизнеса (184)
Автомобили, автосервисы (410)
Аудит и бухгалтерские услуги, юриспруденция (52)
Бытовые услуги, сервис (108)
Горнодобывающая промышленность (4)
Гостиничный бизнес (20)
Государственные, бюджетные структуры (672)
Домашние учет и финансы (146)
Здравоохранение, медицина, стоматология (120)
Издательство, полиграфия, упаковка (11)
ИТ-компания (145)
Кадровые агентства, подбор персонала (23)
Легкая промышленность, мода и одежда (40)
Лесное и деревообрабатывающее хозяйство (13)
Машиностроение и приборостроение (32)
Металлургическая промышленность (7)
Недвижимость, риэлторская деятельность (14)
Обучение, бизнес-тренинг, курсы (24)
Общественные и некоммерческие структуры (24)
Оптовая торговля, дистрибуция, логистика (1041)
Пищевая промышленность (132)
Развлечения, искусство, спорт (55)
Реклама, PR и маркетинг (19)
Рестораны, кафе и фаст-фуд (225)
Розничная и сетевая торговля (FMCG) (1608)
Сельское хозяйство и рыболовство (96)
Страхование (22)
Строительство (116)
Транспорт, автопарки, такси (131)
Туризм и путешествия (10)
Фармацевтика, аптеки (96)
Финансовые услуги, инвестиции (112)
Химическая промышленность (10)
Электротехника и микроэлектроника (9)
Энергетика и ЖКХ (157)
Ювелирная промышленность и торговля (33)

Подпись данных алгоритмами sha aes собственным модулем

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

Быстрый алгоритм шифрования AES ECB 128/192/256

Подпись данных и 1С

Платформа 1С позволяет подписать данные средствами платформы. Для этого необходимо использовать объект МенеджерКриптографии. Данный объект обеспечивает разработчика самым серьёзным инструментом по защите данных. Состав доступных алгоритмов определяется операционной системой и дополнительно установленными в ней модулями криптографии.

Для примера – ниже состав доступных алгоритмов с первых двух попавшихся ОС:

- Каталог готовых решений для 1С"

Таким образом перед разработчиком богатый выбор. Однако, обратите внимание – алгоритма AES в списке нет (128, 192, 256 .. никакого). Выдержка из википедии:

В июне 2003 года Агентство национальной безопасности США постановило, что шифр AES является достаточно надёжным, чтобы использовать его для защиты сведений, составляющих государственную тайну (англ. classified information). Вплоть до уровня SECRET было разрешено использовать ключи длиной 128 бит, для уровня TOP SECRET требовались ключи длиной 192 и 256 бит[8].

То есть не сказать, что он какой-то ничтожный.

Обмен данными между узлами через публичные каналы связи

Подпись данных применяется при авторизации данных в API-запросах. Суть метода заключается в том, чтобы подписать передаваемые данные в пакете и добавить отпечаток подписи в заголовок запроса, например в “X-API-Key”. Через это обеспечивается дополнительная защита от подмены запросов.

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

Использование в этих целях стандартных средств требует дополнительных усилий:

1. Необходимо развернуть систему сертификатов на всех узлах.

2. Сертификаты нужно где-то получать и регулярно обновлять на всех узлах (устанавливать новые). Можно использовать самоподписанные сертификаты действием в 1 год, но такой вариант нежелателен.

Читайте также:  001. Криптография и цифровая подпись RSA-sha256 на платформе 1С

3. Если вы “прохлопаете” сертификат – обмен остановится. Конечно, в случае, когда перед вами стоят очень высокие требования безопасности – это даже хорошо.

А можно что-то попроще?

Действительно – а если я просто хочу на всякий случай добавить подпись данных между своими узлами? Мне бы хотелось иметь один пароль или ключ, раздать его надёжным каналом по всем узлам и пользоваться. Ну там периодически менять его и всё. И желательно, чтоб это всё быстро работало.

Ответ: можно, но понадобится предлагаемая обработка.

Как работает подписание в предлагаемой обработке?

Достаточно просто – получаем хэш и шифруем:

1. На входе получаем подписываемые данные в виде строки или двоичных данных.

2. Получаем из них хэш SHA-256.

3. Далее получаем случайное число, 64 бит. Заполняем им выходной буфер (повторами).

4. Далее получаем отметку времени и XOR-им с серединкой выходного буфера.

5. XOR-им хэш с концом выходного буфера.

6. Шифруем всё секретным ключом.

Поясню пункты 1-5: На выходе получается такая цепочка: случайное число, далее XOR-енная отметка времени и далее XOR-енный хэш. Это нужно для того, чтобы было неизвестно, что зашифровано. Так сложнее организовать атаку с целью получения секретного ключа.

Для описанных ранее целей этого хватит с избытком.

Точно код подписи выглядит вот так:

// Функция - Подписать
//
// Параметры:
//  Данные	 - ДвоичныеДанные, Строка	 - Подписываемые данные
//  Ключ256	 - ДвоичныеДанные	 - Ключ длинной 256 бит
// 
// Возвращаемое значение:
//  ДоичныеДанные - Отпечаток подписи
//
Функция Подписать(Данные, Ключ256) Экспорт
	
	// Получаем хэш SHA-256
	Хеш = Новый ХешированиеДанных(ХешФункция.SHA256);
	Хеш.Добавить(Данные);
	SHA256 = Хеш.ХешСумма;
	
	ЧтениеХэш	= Новый ЧтениеДанных(SHA256);
	БуферХэш	= ЧтениеХэш.ПрочитатьВБуферДвоичныхДанных();
	ЧтениеХэш.Закрыть();
	
	// Формируем данные подписи:
	// R = случайное число 8 байт
	// D = время подписи в секундах XOR R
	// X = Хэш данных XOR (R   R   R   R   R)             
	ВремяСозданияАлгоритма = 63739655820000; // Дата("20202230115700") - Дата("00010101") UTC
	Сейчас = ТекущаяУниверсальнаяДатаВМиллисекундах() - ВремяСозданияАлгоритма;
	ГенераторСлучайныхЧисел = Новый ГенераторСлучайныхЧисел(Сейчас % 4294967295);
	Ч1 = ГенераторСлучайныхЧисел.СлучайноеЧисло();
	Ч2 = ГенераторСлучайныхЧисел.СлучайноеЧисло();
	
	Буфер = Новый БуферДвоичныхДанных(48);
	Буфер.ЗаписатьЦелое32(0, Ч1);
	Буфер.ЗаписатьЦелое32(4, Ч2);
	
	Буфер_R = Буфер.Скопировать();
	
	Буфер.ЗаписатьЦелое64(8, Сейчас);
	Буфер.Записать(16, БуферХэш, 32);
	
	Буфер.ЗаписатьПобитовоеИсключительноеИли(8, Буфер_R, 8);
	Буфер.ЗаписатьПобитовоеИсключительноеИли(16, Буфер_R, 8);
	Буфер.ЗаписатьПобитовоеИсключительноеИли(24, Буфер_R, 8);
	Буфер.ЗаписатьПобитовоеИсключительноеИли(32, Буфер_R, 8);
	Буфер.ЗаписатьПобитовоеИсключительноеИли(40, Буфер_R, 8);
	
	Поток			= Новый ПотокВПамяти(Буфер);
	ДанныеПодписи	= Поток.ЗакрытьИПолучитьДвоичныеДанные();
	
	Возврат ЗашифроватьAES(ДанныеПодписи, Ключ256);
КонецФункции // Подписать

При проверке подписи всё выполняется в обратном порядке:

// Функция - Проверить подпись
//
// Параметры:
//  ПодписанныеДанные	 - Строка, ДвоичныеДанные	 - Подписанные данные
//  ДанныеОтпечатка		 - ДвоичныеДанные	 - Отпечаток подписи
//  Ключ256				 - ДвоичныеДанные	 - Ключ подписи размером 256 бит
// 
// Возвращаемое значение:
//  Структура - Результат сверки подписи. Содержит структуру с полями:
//  * ПодписьВерна - Булево - Результат проверки. Истина - всё в порядке.
//	* ДатаПодписи - Дата - Дата подписания
//	* ДоляСекунды - Число - Доля секунды, в которую происходило подписание.
//
Функция ПроверитьПодпись(ПодписанныеДанные, ДанныеОтпечатка, Ключ256) Экспорт
	
	// Получаем хэш SHA-256
	Хеш = Новый ХешированиеДанных(ХешФункция.SHA256);
	Хеш.Добавить(ПодписанныеДанные);
	SHA256 = Хеш.ХешСумма;
	
	ЧтениеХэш	= Новый ЧтениеДанных(SHA256);
	БуферХэш	= ЧтениеХэш.ПрочитатьВБуферДвоичныхДанных();
	ЧтениеХэш.Закрыть();
	
	// Расшифровываем
	ДанныеПодписи	= РасшифроватьAES(ДанныеОтпечатка, Ключ256);
	ЧтениеПодписи	= Новый ЧтениеДанных(ДанныеПодписи);
	БуферПодписи	= ЧтениеПодписи.ПрочитатьВБуферДвоичныхДанных();
	ЧтениеПодписи.Закрыть();
	
	// Снимаем XOR
	Буфер = Новый БуферДвоичныхДанных(48);
	Буфер.Записать(0, БуферПодписи, 48);
	Буфер.ЗаписатьПобитовоеИсключительноеИли(8, БуферПодписи, 8);
	Буфер.ЗаписатьПобитовоеИсключительноеИли(16, БуферПодписи, 8);
	Буфер.ЗаписатьПобитовоеИсключительноеИли(24, БуферПодписи, 8);
	Буфер.ЗаписатьПобитовоеИсключительноеИли(32, БуферПодписи, 8);
	Буфер.ЗаписатьПобитовоеИсключительноеИли(40, БуферПодписи, 8);
	
	// Получаем результат
	Результат = Новый Структура("ПодписьВерна,ДатаПодписи,ДоляСекунды");
	
	Буфер.ЗаписатьПобитовоеИсключительноеИли(16, БуферХэш, 32);
	КонтрольноеЧисло = Буфер.ПрочитатьЦелое64(16)   Буфер.ПрочитатьЦелое64(24)   Буфер.ПрочитатьЦелое64(32)   Буфер.ПрочитатьЦелое64(40);
	Результат.ПодписьВерна = (КонтрольноеЧисло = 0);
	
	Если Результат.ПодписьВерна Тогда
		ВремяСозданияАлгоритма	= 63739655820000; // Дата("20202230115700") - Дата("00010101") UTC
		ВремяПодписи			= Буфер.ПрочитатьЦелое64(8)   ВремяСозданияАлгоритма;
		Результат.ДатаПодписи	= Дата("00010101")   Цел(ВремяПодписи / 1000);
		Результат.ДоляСекунды	= ВремяПодписи % 1000;
	КонецЕсли;	
	
	Возврат Результат;
КонецФункции // ПроверитьПодпись

Тесты

Обработка тестировалась на платформе 1С:Предприятие 8.3 (8.3.16.1502).

Сеанс выполнялся на ядре с тактовой частотой 1,58 ГГц (максимальная 3,3 ГГц).

За каждую итерацию выполняется подпись и проверка подписи – то есть два действия. В качестве подписываемых данных генерится строка, кратная одному блоку AES (16 байт): от 16 до 512 байт.

Для каждой длины делается 10 итераций и берётся среднее время.

Процедура тестирования:

&НаСервере
Процедура ТестСкоростиНаСервере()
	
	ОбработкаОбъект	= РеквизитФормыВЗначение("Объект");
	СчётчикПаролей	= 1;
	ИсходнаяСтрока	= "";
	
	Для ЧислоБлоков = 1 по 32 Цикл
		
		Данные			= ПолучитьДанные(ЧислоБлоков);
		СреднееВремя	= 0;
		
		Для НомерИтерации = 1 по 10 Цикл
			
			Ключ256			= ПолучитьКлюч256(Формат(СчётчикПаролей, ""));
			СчётчикПаролей	= СчётчикПаролей   1;
			
			Время1 = ТекущаяУниверсальнаяДатаВМиллисекундах(); // СТАРТ!
			
			Результат		= ОбработкаОбъект.Подписать(Данные, Ключ256);
			ИсходныеДанные	= ОбработкаОбъект.ПроверитьПодпись(Данные, Результат, Ключ256);
			
			Время2 = ТекущаяУниверсальнаяДатаВМиллисекундах(); // СТОП!
			
			СреднееВремя	= СреднееВремя   Время2 - Время1;
			
		КонецЦикла;
		
		ТекстСообщения = СтрШаблон(
			"%1;%2"
			,Формат(ЧислоБлоков, "ЧН=; ЧГ=")
			,Формат(СреднееВремя / 10, "ЧРД=,; ЧН=; ЧГ=")
		);
		Сообщить(ТекстСообщения);
	КонецЦикла;
	
КонецПроцедуры

Результат:

- Каталог готовых решений для 1С"

Оцените статью
ЭЦП Эксперт
Добавить комментарий