001. Криптография и цифровая подпись RSA-sha256 на платформе 1С
Разработка - Разработка внешних компонент
Файлы
ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.
| Наименование | Скачано | Купить файл | По подписке PRO |
|---|---|---|---|
|
Обработка "все включено"
.epf 154,77Kb
75
|
75 | 4 200 руб. Купить | 5 SM Скачать |
|
Только внешняя компонента
.dll 8,00Kb
18
|
18 | 3 000 руб. Купить | 2 SM Скачать |
|
Windows приложение для тестирования функциональности
.exe 12,00Kb
13
|
13 | 2 500 руб. Купить | 1 SM Скачать |
|
Исходники
.zip 889,36Kb
21
|
21 | 6 200 руб. Купить | 10 SM Скачать |
Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний
Оформите подписку на компанию для решения рабочих задач
Оформить подписку и скачать решение со скидкойВы можете заказать платную доработку или адаптацию этой разработки под вашу конфигурацию на «Бирже заказов».
- 0% комиссии — оплата напрямую исполнителю;
- Исполнители любого масштаба — от отдельных специалистов до команд под проект;
- Прямой обмен контактами между заказчиком и исполнителем;
- Безопасная сделка — при необходимости;
- Рейтинги, кейсы и прозрачная система откликов.
Эта статья описывает готовое решение для выполнения задач по формированию цифровых подписей, проверке подписей, а так же шифрованию и дешифрованию данных.
Обмен с онлайн кассами, биткоины – часто встречающиеся в моей практике темы для разработки, в которых используется шифрование передаваемых данных. В моем случае, под шифрованием я подразумеваю в т.ч. формирование электронной цифровой подписи с последующей валидацией.
Прошу помнить, что разработка средств криптографии регулируется Федеральным Законом "О лицензировании отдельных видов деятельности" а значит требует наличия лицензии, поэтому прежде чем использовать приведенное ниже решение в коммерческих целях прошу ознакомиться законом.
Маленькая оговорка: в действительности лицензирование требуется только в том случае, если вы продаёте программное средство, то есть осуществляете предпринимательскую деятельность. В случае если вы делаете это программное средство для себя и своего предприятия, то это выходит за рамки ФЗ "О лицензировании отдельных видов деятельности" (в следствие отсутствия деятельности как таковой).
Когда мне была поставлена задача реализовать подписание ЭЦП по алгоритму SHA256-rca паддинг pkcs1 с ключами 2048 я решил, что сделаю все в 3 строки кода:
Хэш=Новый ХешированиеДанных(ХешФункция.SHA256);
Хэш.Добавить("Тра ля ля");
Сообщить(Хэш.ХешСумма);
Как выяснилось почти сразу, кроме этих магический строк в платформу встроены еще пара других алгоритмов получения хэшей и все.
Но где же RSA? А ключи? Короче ждал меня облом.
Можно задействовать внешний криптопровайдер, но это стоит денег, да и сервер на котором все должно работать находится в Америке и там же админится, дадут ли устанавливать лишний софт – большой вопрос.
Поиски в интернете готового решения не дали, пришлось садиться в студию и кодить компоненту net.
Для запуска компоненты используется C++ компонента NETLoader, скачанная с инфостарта.
В архивах к публикации можно найти демо-обработку, реализующую логику шифрования/дешифрования, создания и проверки цифровой подписи, и компоненты отдельно.
Все процедуры выполняются в один поток и на больших данных могут подвисать. Но на практике мне такое не встретилось.
В этом видео показано как все работает:
подписание по алгоритму 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с шифрование RSA sha256 внешняя компонента
См. также
Разработка внешних компонент Телефония, SIP Разработчик 1С:Предприятие 8 1C:Бухгалтерия Россия Платные (руб)
Внешняя компонента выполнена по технологии Native API для 1С 8.х, обеспечивает доступ к программным АТС Asterisk (FreePBX, Elastix) через AMI интерфейс. Через него можно управлять многими функциями Asterisk (определение номеров, перевод звонков, набор телефона и т. д.)
5246 руб.
04.05.2018 52182 128 68
Разработка внешних компонент Разработчик 1С:Предприятие 8 1C:Бухгалтерия 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия 3.0 Платные (руб)
Внешняя компонента позволяет работать c TWAIN-совместимым оборудованием (сканерами, камерами) . Полностью совместима со стандартной TWAIN-компонентой из БСП и может применяться как ее замена без изменения вызовов, при этом может работать с 64-разрядной платформой, а так же имеет расширенную функциональность, например, сохранение результата непосредственно в PDF без использования сторонних утилит. Прекрасно работает на сервере, тонком клиенте и веб-клиенте (проверена работа в браузерах Google Chrome, Mozilla Firefox и Microsoft Internet Explorer).
5084 руб.
12.05.2020 34935 147 100
Разработка внешних компонент Инструментарий разработчика Разработчик 1С 8.3 Бесплатно (free)
Внешняя обработка проверяет выгрузку конфигурации, расширений и внешних обработок и находит места, где код руками делает то, что платформа умеет штатно: регулярки через COM, пауза пустым циклом, свой хеш и Base64, распаковка архивов программой, буфер обмена через HTML-поле. По каждой находке пишет, доступна ли замена на месте или мешает тонкий клиент.
13.10.2026 1264 144 nedomolkov.ivan 5
Разработка внешних компонент Разработчик 1С:Предприятие 8 Бесплатно (free)
Нативная внешняя компонента для 1С 8 для чтения файлов Excel без установленного Excel и делает это быстро, файл 68МБ загружается в таблицу значений ~1 секунду. Компонента поддерживает чтение двух форматов: Excel 2007+ и Excel 97-2003 Формат файла определяется автоматически по сигнатуре (первые 8 байт файла), а не по расширению. Позволяет открывать XLS и XLSX файлы и получать содержимое листов в виде ТаблицыЗначений или JSON-массива.
03.07.2026 2350 skyadmin 31
Разработка внешних компонент Разработчик 1С 8.3 Бесплатно (free)
В современных корпоративных решениях на платформе 1С:Предприятие 8.3 всё чаще возникает потребность в визуальном моделировании и автоматизации бизнес-процессов с использованием нотации BPMN 2.0. Стандартные средства платформы не предоставляют полноценного редактора BPMN, однако интеграция открытой библиотеки bpmn-js позволяет реализовать интерактивное моделирование бизнес-процессов непосредственно в 1С. В статье рассмотрены архитектура решения, пошаговая инструкция по сборке библиотеки из исходников для WebKit, а также примеры программного взаимодействия между 1С и JavaScript.
03.04.2026 4248 SultanovStas 8
Разработка внешних компонент Разработчик 1С 8.3 Россия Бесплатно (free)
Создать NativeAPI-компоненту для Python-скриптов? Это просто!
20.10.2025 10992 IlyaKuznetsov 10
Разработка внешних компонент Системный администратор Разработчик Стажер Бесплатно (free)
Библиотека для работы с базами SQLite из 1С на основе внешней компоненты. Для Linux и Windows, бесплатно и с открытым исходным кодом!
14.01.2025 8202 bayselonarrend 17
Разработка внешних компонент Разработчик 1С:Предприятие 8 Россия Бесплатно (free)
В статье описывается приложение-конструктор внешних компонент (native API). Конструктор упрощает процесс разработки за счет удобного добавления всех нужных функций и процедур в графическом режиме, с указанием их параметров и типов параметров. На выходе приложение генерирует готовый код на С++ и Rust и позволяет сразу приступить к реализации, без настройки API компоненты вручную.
04.12.2024 13774 kovalevdmv 29
Это большая редкость, когда автор не просто выкладывает бинарник (с х.з. каким кодом внутри), а дает возможность самому проверить код и собрать его.
У меня вопрос. Я вообще не владею .Net, и не люблю его (исторически сложилось).
Насколько проще/сложнее писать Native ВК для 1С на .Net, нежели на расово верном C++ (или хотя бы Dephi)?
"Да-да, конечно". Для некоторых это и правда невозможно.
С таким же успехом можно сказать, что любая программа на .NET не является программой, так как не написана на машинном коде.
ИмяФайла=КаталогОтчета+"\AddInNetObjectToNative.dll";
ПодключитьВнешнююКомпоненту(ИмяФайла, "NetObjectToNative",ТипВнешнейКомпоненты.Native); Мне вот все равно, правы Вы или нет. Просто интересно стало: у Вас много лишнего времени? Потратьте его на семью...
П,С, пока вы строчите комментарии я решаю задачи, пусть и не идеальным/оптимальным методом - я уже перерос юношеский максимализм.
С# использую, потому что знаю. С++ не знаю, учить не хочу, даже если на основы достаточно потратить 1 день.
Хеширование = Новый ХешированиеДанных(ХешФункция.SHA256);
Хеширование.Добавить(JWTдляСигнатуры);
Хеш = Хеширование.ХешСумма;
ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
ХМЛСертификатСЗакрытымКлючом = ОбработкаОбъект.ПолучитьМакет("Макет");
ХМЛТекст = ПолучитьСтрокуИзДвоичныхДанных(ХМЛСертификатСЗакрытымКлючом);
КрПровайдер = Новый COMОбъект("System.Security.Cryptography.RSACryptoServiceProvider");
КрПровайдер.FromXmlString(ХМЛТекст);
SafeArrayBinХешДляПодписи = SafeИзДвоичных(Хеш);
SafeArrayBinПодписьДвоичная = КрПровайдер.SignHash(SafeArrayBinХешДляПодписи, "SHA256");
ПодписьДвоичная = ДвоичныеИзSafe(SafeArrayBinПодписьДвоичная);
Показатьэтот "виндовский криптопровайдер" не встроен в видну. Это библиотека того самого "дотнет" framework.
(10)
Для приведенного примера да, не нужен. Намного интересней, когда понадобится использовать гостовский криптопровайдер.
Спорное утверждение. С точки зрения использования актуальной версии, ее приходится устанавливать как отдельное приложение.
(14)
Это в корне не верно. CryptoAPI это интерфейс, который как содержит свою реализацию криптопровайдера, так и может использовать сторонний. В данном случае System.Security.Cryptography.RSACryptoServiceProvider это сторонний криптопровайдер, который реализует интерфейс CryptoAPI. Т.е. это через CryptoAPI можно использовать криптопровайдер "дотнет".
Решение с ВК может работать и на unix. Не знаю как сделано у автора, но теоретически это возможно.
Соответственно нужно использовать класс "System.Security.Cryptography.Algorithms".
Компонента решает намного больше задач, чем просто создание цифровой подписи.
Но самое главное - не это. Полный интернет примеров кода, на всех языках, кроме 1с) Потому, какой пример (работающий) нашел, на том языке и скомпилил.
Напишите на 1с шифрование данных этим же алгоритмом. Уверен, сообществу будет благодарно.
Главное - не язык или технология, а решение задачи заказчика в рамках бюджета и сроков с приемлемым уровнем качества.
ПодписьВерна = КрПровайдер.VerifyHash (SafeArrayBinХешДляПодписи, "SHA256", SafeArrayBinПодписьДвоичная);Лучшее решение - это то, которое решает задачу заказчика, в приемлемый срок с приемлемым качеством в рамках бюджета.
Коллега, уже не раз пишу, что функционал компоненты выходит за рамки создания ЭЦП. Почитайте описание хотя бы.
COMSafeArray = Новый COMSafeArray("VT_UI1", Байтов);//однобайтовый без знакаПример получения ЭЦП в base64:
PrivateKey = ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища("PrivateKey");
ОбъектШифрования = Новый COMОбъект("System.Security.Cryptography.RSACryptoServiceProvider");
ОбъектШифрования.FromXmlString(PrivateKey);
ВходнаяСтрока = "Test string";
UTF8Encoding = Новый COMОбъект("System.Text.UTF8Encoding");
ДаныеБинарные = UTF8Encoding.GetBytes_4(ВходнаяСтрока);
//Получаем подпись
BinaryЭЦП = ОбъектШифрования.SignData_2(ДаныеБинарные, "2.16.840.1.101.3.4.2.3"); //SHA512RSA OUT:ComSafeArray
ЭЦП = BinaryЭЦП.Выгрузить(); //ComSafeArray -> Массив
Размер = ЭЦП.Количество();
Буфер = Новый БуферДвоичныхДанных(Размер); //Массив -> БуферДвоичныхДанных
Для Н = 0 По Размер - 1 Цикл
Буфер[Н] = ЭЦП[Н];
КонецЦикла;
ВыходнаяСтрока = ПолучитьBase64СтрокуИзБуфераДвоичныхДанных(Буфер);// БуферДвоичныхДанных -> Base64 String
Сообщить(СтрЗаменить(ВыходнаяСтрока, Символ(13) + Символ(10), ""));
Показать$cert = New-Object system.security.cryptography.x509certificates.x509certificate2
$pat="d:\UNSAFE\del\PrivateKey.pfx"
$password="123"
$flags = "UserKeySet,Exportable"
$cert.Import($pat, $password, $flags)
$myXml = $cert.PrivateKey.ToXmlString($True)
$myXml | Out-File "d:\UNSAFE\del\PrivateKey.xml"
Для безопасного хранения закрытого ключа xml - можно зашифровать его средствами 1С:
//шифруем ХМЛ
МенеджерКриптографии = Новый МенеджерКриптографии("Microsoft Enhanced Cryptographic Provider v1.0","",1);
ХранилищеСертификатов = МенеджерКриптографии.ПолучитьХранилищеСертификатов(ТипХранилищаСертификатовКриптографии.ПерсональныеСертификаты);
Сертификат = ХранилищеСертификатов.НайтиПоОтпечатку(ПолучитьДвоичныеДанныеИзHexСтроки("908407f45198d4dd3a544c16d6b1a0cac85340cd"));
ДвоичныеКлючаХМЛ = Новый ДвоичныеДанные("d:\UNSAFE\del\PrivateKey.xml");
ДвоичныеЗашифрованногоХМЛ = МенеджерКриптографии.Зашифровать(ДвоичныеКлючаХМЛ, Сертификат);
СтрокаЗашифрованныеХМЛ = Base64Строка(ДвоичныеЗашифрованногоХМЛ);
//расшифровываем ХМЛ
//МенеджерКриптографии.ПарольДоступаКЗакрытомуКлючу = "123";
ДвоичныеЗашифрованногоХМЛ = Base64Значение(СтрокаЗашифрованныеХМЛ);
ДвоичныеРасшифрованы = МенеджерКриптографии.Расшифровать(ДвоичныеЗашифрованногоХМЛ);
СтрокаХМЛ = ПолучитьСтрокуИзДвоичныхДанных(ДвоичныеРасшифрованы);
Сообщить(СтрокаХМЛ);
ПоказатьBinaryЭЦП = ОбъектШифрования.SignData_2(ДаныеБинарные, "2.16.840.1.101.3.4.2.3"); //SHA512RSA OUT:ComSafeArray&НаКлиенте
Процедура ТестГуглТаблица(Команда)
ТестГуглТаблицаНаСервере();
КонецПроцедуры
&НаСервере
Процедура ТестГуглТаблицаНаСервере()
JWTдляСигнатуры = JWTдляСигнатуры();
Хеширование = Новый ХешированиеДанных(ХешФункция.SHA256);
Хеширование.Добавить(JWTдляСигнатуры);
Хеш = Хеширование.ХешСумма;
ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
МакетЗакрытогоКлюча = ОбработкаОбъект.ПолучитьМакет("Макет");
ХМЛТекст = ПолучитьСтрокуИзДвоичныхДанных(МакетЗакрытогоКлюча);
КрПровайдер = Новый COMОбъект("System.Security.Cryptography.RSACryptoServiceProvider");
КрПровайдер.FromXmlString(ХМЛТекст);
SafeArrayBinХешДляПодписи = SafeИзДвоичных(Хеш);
SafeArrayBinПодписьДвоичная = КрПровайдер.SignHash(SafeArrayBinХешДляПодписи, "SHA256");
ПодписьДвоичная = ДвоичныеИзSafe(SafeArrayBinПодписьДвоичная);
Подпись64 = Base64Url(ПодписьДвоичная);
JWTдляСигнатуры = СтрЗаменить(JWTдляСигнатуры,"{","");
JWTдляСигнатуры = СтрЗаменить(JWTдляСигнатуры,"}","");
JWT = JWTдляСигнатуры + "."+Подпись64;
OpenSSL = Новый ЗащищенноеСоединениеOpenSSL();
HTTPСоединение = Новый HTTPСоединение("www.googleapis.com",,,,,,OpenSSL);
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");
grant_type = "urn:ietf:params:oauth:grant-type:jwt-bearer";
grant_type = КодироватьСтроку(grant_type,СпособКодированияСтроки.КодировкаURL);
HTTPЗапрос = Новый HTTPЗапрос("/oauth2/v4/token", Заголовки);
HTTPЗапрос.УстановитьТелоИзСтроки("grant_type="+grant_type+"&assertion="+JWT);
Ответ = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
СтрокаОтвета = Ответ.ПолучитьТелоКакСтроку();
ЧтениеЖсон = Новый ЧтениеJSON;
ЧтениеЖсон.УстановитьСтроку(СтрокаОтвета);
СтруктураОтвета = ПрочитатьJSON(ЧтениеЖсон);
Токен = СтруктураОтвета.access_token;
Сообщить(Токен);
HTTPСоединение = Новый HTTPСоединение("sheets.googleapis.com",,,,,,OpenSSL);
урл = "/v4/spreadsheets/1H_nu10s9gB787gy4Qhx2bbCyGPrfRnkGGEuZrtV4-0s/values/Sheet1!A1?valueInputOption=RAW";
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json; charset=UTF-8");
Заголовки.Вставить("Authorization", "Bearer " + Токен);
СтрокаJson = "{""range"":""Sheet1!A1"", ""values"":[[777999000]],}";
HTTPЗапрос2 = Новый HTTPЗапрос(урл, Заголовки);
HTTPЗапрос2.УстановитьТелоИзСтроки(СтрокаJson);
Ответ = HTTPСоединение.Записать(HTTPЗапрос2);
СтрокаОтвета = Ответ.ПолучитьТелоКакСтроку();
Сообщить(СтрокаОтвета);
КонецПроцедуры
&НаСервере
Функция ПолучитьСтрокуЖсон(СтруктураДляЖсон)
ЗаписьJson = Новый ЗаписьJson;
ЗаписьJson.УстановитьСтроку(Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет));
ЗаписатьJSON(ЗаписьJson, СтруктураДляЖсон);
Возврат ЗаписьJson.Закрыть();
КонецФункции // ПолучитьСтрокуЖсон(СтруктураДляЖсон)
&НаСервере
//create base64url header + clame for jwt
//https://developers.google.com/identity/protocols/OAuth2ServiceAccount
//на странице ↑ найти и кликнуть HTTP/REST
Функция JWTдляСигнатуры()
//это все время одинаковое, можно сразу base64урл
СтруктураДляЖсон = Новый Структура;
СтруктураДляЖсон.Вставить("alg", "RS256");
СтруктураДляЖсон.Вставить("typ", "JWT");
СтруктураДляЖсон.Вставить("alg", "RS256");
СтрокаЖсонХедер = ПолучитьСтрокуЖсон(СтруктураДляЖсон);
Хедер64 = Base64Url(ПолучитьДвоичныеДанныеИзСтроки(СтрокаЖсонХедер));
СтруктураДляЖсон.Очистить();
//iss The email address of the service account.
СтруктураДляЖсон.Вставить("iss", "xxx*xxx.iam.gserviceaccount.com");
//scope A space-delimited list of the permissions that the application requests.
//смотреть что нужно например:
СтруктураДляЖсон.Вставить("scope", "https://www.googleapis.com/auth/spreadsheets");
//aud A descriptor of the intended target of the assertion.
//When making an access token request this value is always .
СтруктураДляЖсон.Вставить("aud", "https://www.googleapis.com/oauth2/v4/token");
//exp The expiration time of the assertion, specified as seconds since 00:00:00 UTC, January 1, 1970.
//This value has a maximum of 1 hour after the issued time.
ВремяДо = УниверсальноеВремя(ТекущаяДата())+60*60;// запас на поправку времени
СекундДо = ВремяДо - Дата(1970,1,1);
СтруктураДляЖсон.Вставить("exp", СекундДо);
//iat The time the assertion was issued, specified as seconds since 00:00:00 UTC, January 1, 1970.
СтруктураДляЖсон.Вставить("iat", СекундДо-60*60);
СтрокаЖсонКлэймСет = ПолучитьСтрокуЖсон(СтруктураДляЖсон);;
КлэймСет64 = Base64Url(ПолучитьДвоичныеДанныеИзСтроки(СтрокаЖсонКлэймСет));
Возврат Хедер64+"."+КлэймСет64;
КонецФункции
&НаСервере
//существует изменённый Base64 для URL, где не используется заполнение символом =
//и символы + и / соответственно заменяются на * и -
//Base64-кодирования URL адресов признается вариант,
//когда символы + и / заменяются, соответственно, на - и _ (RFC 3548, раздел 4).
Функция Base64Url(ДвоичныеДанные)
бейс64строка = Base64Строка(ДвоичныеДанные);
бейс64строка = стрЗаменить(бейс64строка, "+", "-");
бейс64строка = стрЗаменить(бейс64строка, "/", "_");
бейс64строка = стрЗаменить(бейс64строка, Символы.ВК, "");
бейс64строка = стрЗаменить(бейс64строка, Символы.ПС, "");
Если Прав(бейс64строка, 2) = "==" Тогда
бейс64строка = Лев(бейс64строка,СтрДлина(бейс64строка)-2);
ИначеЕсли Прав(бейс64строка, 1) = "=" Тогда
бейс64строка = Лев(бейс64строка,СтрДлина(бейс64строка)-1);
КонецЕсли;
Возврат бейс64строка;
КонецФункции
&НаСервере
Функция SafeИзUTF(strUtf)
Буфер = ПолучитьБуферДвоичныхДанныхИзСтроки(strUtf);
Байтов = Буфер.Размер;
COMSafeArray = Новый COMSafeArray("VT_UI1", Байтов);//однобайтовый без знака
Для сч = 0 по Байтов-1 Цикл
COMSafeArray.SetValue(сч, Буфер.Получить(сч));
КонецЦикла;
Возврат COMSafeArray;
КонецФункции
&НаСервере
Функция SafeИзДвоичных(ДвоичныеДанные)
Буфер = ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(ДвоичныеДанные);
Байтов = Буфер.Размер;
COMSafeArray = Новый COMSafeArray("VT_UI1", Байтов);//однобайтовый без знака
Для сч = 0 по Байтов-1 Цикл
COMSafeArray.SetValue(сч, Буфер.Получить(сч));
КонецЦикла;
Возврат COMSafeArray;
КонецФункции
&НаСервере
Функция ДвоичныеИзSafe(SafeArrayBin)
Буфер = Новый БуферДвоичныхДанных(SafeArrayBin.GetLength());
Для сч = 0 по SafeArrayBin.GetUpperBound() Цикл
Буфер.Установить(сч, SafeArrayBin.GetValue(сч));
КонецЦикла;
Возврат ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(Буфер);
КонецФункции
ПоказатьОбработкаОбъект = РеквизитФормыВЗначение("Объект");
МакетЗакрытогоКлюча = ОбработкаОбъект.ПолучитьМакет("Макет");
ХМЛТекст = ПолучитьСтрокуИзДвоичныхДанных(МакетЗакрытогоКлюча);
КрПровайдер = Новый COMОбъект("System.Security.Cryptography.RSACryptoServiceProvider");
КрПровайдер.FromXmlString(ХМЛТекст);
SafeArrayBinХешДляПодписи = SafeИзДвоичных(Хеш);
SafeArrayBinПодписьДвоичная = КрПровайдер.SignHash(SafeArrayBinХешДляПодписи, "SHA256");
ПодписьДвоичная = ДвоичныеИзSafe(SafeArrayBinПодписьДвоичная);
Подскажите пожалуйста, подпись формируется открепленная или прикрепленная? Не нашел в описании RSACryptoServiceProvider параметр, который бы указывал на это.
У меня есть необходимость подписать строку JSON по алгоритму RSA SHA-256. Чтобы получился итоговый контейнер pkcs7, который будет включать в себя исходные данные, подпись и сертификат. При помощи менеджера криптографии у меня получилось сделать так, но подпись так же открепленная, а нужно прикрепленную:
МенеджерКриптографии = Новый МенеджерКриптографии("Microsoft Enhanced RSA and AES Cryptographic Provider", "", 24);
МенеджерКриптографии.АлгоритмХеширования = "SHA-256";
МенеджерКриптографии.АлгоритмПодписи = "RSA_SIGN";
Хранилище = МенеджерКриптографии.ПолучитьХранилищеСертификатов(ТипХранилищаСертификатовКриптографии.ПерсональныеСертификаты);
СписокСертфикатов = Хранилище.ПолучитьВсе();
Сертификат = Хранилище.НайтиПоОтпечатку(ПолучитьДвоичныеДанныеИзHexСтроки("d9be17330c698c1d7b7a43f9fc93bca*********"));
СтрокаJSON = ПолучитьСтрокуJSON();
JsonДвоичныеДанные = ПолучитьДвоичныеДанныеИзСтроки(СтрокаJSON);
Подпись = МенеджерКриптографии.Подписать(JsonДвоичныеДанные, Сертификат);
ПодписьBase64 = Base64Строка(Подпись); ПоказатьНе подскажите каким способом можно подписать исходные данные чтобы в итоге получилась прикрепленная подпись?
Суть такова: от банка получаю ответ хттп строку которая содержит хэдер в base64 и зашифрованый payload такого вида:
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzaWduYWxDb2RlIjoiUGF5bWVudCIsInNpZ25hbER0VG0iOiIyMDI1LTA4
Строка разделена 3 точками.
До первой точки это вроде зашифрованный в base64 хэдер который если расшифровать получаем {"alg":"RS256","typ":"JWT"}
От первой до второй точки и есть нужные мне данные, зашифрованный payload....
Из банка также выдали сертификат....
Помогите пожалуйста разобраться как все это дело расшифровать...
Хотя в принципе, RSA пригоден и для шифрования данных небольших размеров, но в случае шифрования никакой хеш вообще не нужен (в т.ч. 256-й SHA)
&НаСервере
Функция SafeИзДвоичных(ДвоичныеДанные)
Буфер = ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(ДвоичныеДанные);
Байтов = Буфер.Размер;
COMSafeArray = Новый COMSafeArray("VT_UI1", Байтов);//однобайтовый без знака
Для сч = 0 по Байтов-1 Цикл
COMSafeArray.SetValue(сч, Буфер.Получить(сч));
КонецЦикла;
Возврат COMSafeArray;
КонецФункции
&НаСервере
Функция ДвоичныеИзSafe(SafeArrayBin)
Буфер = Новый БуферДвоичныхДанных(SafeArrayBin.GetLength());
Для сч = 0 по SafeArrayBin.GetUpperBound() Цикл
Буфер.Установить(сч, SafeArrayBin.GetValue(сч));
КонецЦикла;
Возврат ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(Буфер);
КонецФункции
Показать&НаКлиенте
Процедура ТестГуглТаблица(Команда)
ТестГуглТаблицаНаСервере();
КонецПроцедуры
&НаСервере
Процедура ТестГуглТаблицаНаСервере()
JWTдляСигнатуры = JWTдляСигнатуры();
Хеширование = Новый ХешированиеДанных(ХешФункция.SHA256);
Хеширование.Добавить(JWTдляСигнатуры);
Хеш = Хеширование.ХешСумма;
ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
МакетЗакрытогоКлюча = ОбработкаОбъект.ПолучитьМакет("Макет");
ХМЛТекст = ПолучитьСтрокуИзДвоичныхДанных(МакетЗакрытогоКлюча);
КрПровайдер = Новый COMОбъект("System.Security.Cryptography.RSACryptoServiceProvider");
КрПровайдер.FromXmlString(ХМЛТекст);
SafeArrayBinХешДляПодписи = SafeИзДвоичных(Хеш);
SafeArrayBinПодписьДвоичная = КрПровайдер.SignHash(SafeArrayBinХешДляПодписи, "SHA256");
ПодписьДвоичная = ДвоичныеИзSafe(SafeArrayBinПодписьДвоичная);
Подпись64 = Base64Url(ПодписьДвоичная);
JWTдляСигнатуры = СтрЗаменить(JWTдляСигнатуры,"{","");
JWTдляСигнатуры = СтрЗаменить(JWTдляСигнатуры,"}","");
JWT = JWTдляСигнатуры + "."+Подпись64;
OpenSSL = Новый ЗащищенноеСоединениеOpenSSL();
HTTPСоединение = Новый HTTPСоединение("www.googleapis.com",,,,,,OpenSSL);
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");
grant_type = "urn:ietf:params:oauth:grant-type:jwt-bearer";
grant_type = КодироватьСтроку(grant_type,СпособКодированияСтроки.КодировкаURL);
HTTPЗапрос = Новый HTTPЗапрос("/oauth2/v4/token", Заголовки);
HTTPЗапрос.УстановитьТелоИзСтроки("grant_type="+grant_type+"&assertion="+JWT);
Ответ = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
СтрокаОтвета = Ответ.ПолучитьТелоКакСтроку();
ЧтениеЖсон = Новый ЧтениеJSON;
ЧтениеЖсон.УстановитьСтроку(СтрокаОтвета);
СтруктураОтвета = ПрочитатьJSON(ЧтениеЖсон);
Токен = СтруктураОтвета.access_token;
Сообщить(Токен);
HTTPСоединение = Новый HTTPСоединение("sheets.googleapis.com",,,,,,OpenSSL);
урл = "/v4/spreadsheets/1H_nu10s9gB787gy4Qhx2bbCyGPrfRnkGGEuZrtV4-0s/values/Sheet1!A1?valueInputOption=RAW";
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json; charset=UTF-8");
Заголовки.Вставить("Authorization", "Bearer " + Токен);
СтрокаJson = "{""range"":""Sheet1!A1"", ""values"":[[777999000]],}";
HTTPЗапрос2 = Новый HTTPЗапрос(урл, Заголовки);
HTTPЗапрос2.УстановитьТелоИзСтроки(СтрокаJson);
Ответ = HTTPСоединение.Записать(HTTPЗапрос2);
СтрокаОтвета = Ответ.ПолучитьТелоКакСтроку();
Сообщить(СтрокаОтвета);
КонецПроцедуры
&НаСервере
Функция ПолучитьСтрокуЖсон(СтруктураДляЖсон)
ЗаписьJson = Новый ЗаписьJson;
ЗаписьJson.УстановитьСтроку(Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет));
ЗаписатьJSON(ЗаписьJson, СтруктураДляЖсон);
Возврат ЗаписьJson.Закрыть();
КонецФункции // ПолучитьСтрокуЖсон(СтруктураДляЖсон)
&НаСервере
//create base64url header + clame for jwt
//https://developers.google.com/identity/protocols/OAuth2ServiceAccount
//на странице ↑ найти и кликнуть HTTP/REST
Функция JWTдляСигнатуры()
//это все время одинаковое, можно сразу base64урл
СтруктураДляЖсон = Новый Структура;
СтруктураДляЖсон.Вставить("alg", "RS256");
СтруктураДляЖсон.Вставить("typ", "JWT");
СтруктураДляЖсон.Вставить("alg", "RS256");
СтрокаЖсонХедер = ПолучитьСтрокуЖсон(СтруктураДляЖсон);
Хедер64 = Base64Url(ПолучитьДвоичныеДанныеИзСтроки(СтрокаЖсонХедер));
СтруктураДляЖсон.Очистить();
//iss The email address of the service account.
СтруктураДляЖсон.Вставить("iss", "xxxxxxxxxxxxxx*dans-test-project-xxxxxxxxx.iam.gserviceaccount.com");
//scope A space-delimited list of the permissions that the application requests.
//смотреть что нужно например:
СтруктураДляЖсон.Вставить("scope", "https://www.googleapis.com/auth/spreadsheets");
//aud A descriptor of the intended target of the assertion.
//When making an access token request this value is always .
СтруктураДляЖсон.Вставить("aud", "https://www.googleapis.com/oauth2/v4/token");
//exp The expiration time of the assertion, specified as seconds since 00:00:00 UTC, January 1, 1970.
//This value has a maximum of 1 hour after the issued time.
ВремяДо = УниверсальноеВремя(ТекущаяДата())+60*60;// запас на поправку времени
СекундДо = ВремяДо - Дата(1970,1,1);
СтруктураДляЖсон.Вставить("exp", СекундДо);
//iat The time the assertion was issued, specified as seconds since 00:00:00 UTC, January 1, 1970.
СтруктураДляЖсон.Вставить("iat", СекундДо-60*60);
СтрокаЖсонКлэймСет = ПолучитьСтрокуЖсон(СтруктураДляЖсон);;
КлэймСет64 = Base64Url(ПолучитьДвоичныеДанныеИзСтроки(СтрокаЖсонКлэймСет));
Возврат Хедер64+"."+КлэймСет64;
КонецФункции
&НаСервере
//существует изменённый Base64 для URL, где не используется заполнение символом =
//и символы + и / соответственно заменяются на * и -
//Base64-кодирования URL адресов признается вариант,
//когда символы + и / заменяются, соответственно, на - и _ (RFC 3548, раздел 4).
Функция Base64Url(ДвоичныеДанные)
бейс64строка = Base64Строка(ДвоичныеДанные);
бейс64строка = стрЗаменить(бейс64строка, "+", "-");
бейс64строка = стрЗаменить(бейс64строка, "/", "_");
бейс64строка = стрЗаменить(бейс64строка, Символы.ВК, "");
бейс64строка = стрЗаменить(бейс64строка, Символы.ПС, "");
Если Прав(бейс64строка, 2) = "==" Тогда
бейс64строка = Лев(бейс64строка,СтрДлина(бейс64строка)-2);
ИначеЕсли Прав(бейс64строка, 1) = "=" Тогда
бейс64строка = Лев(бейс64строка,СтрДлина(бейс64строка)-1);
КонецЕсли;
Возврат бейс64строка;
КонецФункции
&НаСервере
Функция SafeИзUTF(strUtf)
Буфер = ПолучитьБуферДвоичныхДанныхИзСтроки(strUtf);
Байтов = Буфер.Размер;
COMSafeArray = Новый COMSafeArray("VT_UI1", Байтов);//однобайтовый без знака
Для сч = 0 по Байтов-1 Цикл
COMSafeArray.SetValue(сч, Буфер.Получить(сч));
КонецЦикла;
Возврат COMSafeArray;
КонецФункции
&НаСервере
Функция SafeИзДвоичных(ДвоичныеДанные)
Буфер = ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(ДвоичныеДанные);
Байтов = Буфер.Размер;
COMSafeArray = Новый COMSafeArray("VT_UI1", Байтов);//однобайтовый без знака
Для сч = 0 по Байтов-1 Цикл
COMSafeArray.SetValue(сч, Буфер.Получить(сч));
КонецЦикла;
Возврат COMSafeArray;
КонецФункции
&НаСервере
Функция ДвоичныеИзSafe(SafeArrayBin)
Буфер = Новый БуферДвоичныхДанных(SafeArrayBin.GetLength());
Для сч = 0 по SafeArrayBin.GetUpperBound() Цикл
Буфер.Установить(сч, SafeArrayBin.GetValue(сч));
КонецЦикла;
Возврат ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(Буфер);
КонецФункции
ПоказатьС помощью Менеджера Криптографии делаю как в примере на ИТС:
Сертификат = Список[0];
Данные = ПолучитьИзВременногоХранилища(ПомещенныйФайл.Адрес);
МенеджерКриптографии = Новый МенеджерКриптографии("Microsoft Enhanced Cryptographic Provider v1.0", "", 1);
ИмяФайла = Ждать МенеджерКриптографии.ПодписатьАсинх(Данные, ПомещенныйФайл.СсылкаНаФайл.Файл.Путь + "Подписанный.p7s", Сертификат);
МенеджерКриптографии.ПарольДоступаКЗакрытомуКлючу = ПолучитьПарольДоступа();
ИмяФайла = Ждать МенеджерКриптографии.ПодписатьАсинх(Данные, ПомещенныйФайл.СсылкаНаФайл.Файл.Путь + "Подписанный.p7s", Сертификат);
Но тут же менеджер будет ругаться на тип провайдера, т.к. они не поддерживают SHA256.
ДаныеБинарные = UTF8Encoding.GetBytes_4(ВходнаяСтрока); //ДаныеБинарные COMSafeArray
Это значит, что с тем же успехом можете двоичные данные файла преобразовать в COMSafeArray и передать их в COM на подпись (SignData). Смотрите (64) SafeИзДвоичных
Только обратите внимание, что в (56) SHA-512, а Вам нужен SHA-256
Получаю ошибку на строке $myXml = $cert.PrivateKey.ToXmlString($True)
Нельзя вызвать метод для выражения со значением null.
Получается у меня с сертификатом что-то не то и он не определяется как объект? Или что может быть?
Уже на строках ругается:
$cert.Import($pat, $password, $flags)
$cert.GetRSAPrivateKey()
Сбой вызова метода из-за отсутствия в [System.Security.Cryptography.X509Certificates.X509Certificate2] метода с именем
"GetRSAPrivateKey".
Наследование в программировании - это принцип объектно-ориентированного программирования, который позволяет создавать иерархии классов: дочерние классы наследуют данные и методы от родительских классов.
ПодключитьВнешнююКомпоненту("ОбщийМакет.NETLoader", "NET") ;
Компонента = Новый("AddIn.NET.NETLoader");
Компонента.CreateObjectFromFile("C:\coderEncoder.dll", ???);
sign = джейсон строка для подписи;
// получаем хэш мд5 в виде двоичных данных
Хеш = Новый ХешированиеДанных(ХешФункция.MD5);
Хеш.Добавить(sign);
sign = Хеш.ХешСумма;
//подписываем
КрПровайдер = Новый COMОбъект("System.Security.Cryptography.RSACryptoServiceProvider");
КрПровайдер.FromXmlString(ХМЛТекст); //здесь хмл строка приватного ключа
SafeArrayBinХешДляПодписи = SafeИзДвоичных(sign); Показать//SafeArrayBinПодписьДвоичная = КрПровайдер.SignHash(SafeArrayBinХешДляПодписи, "SHA256"); - эта строка не падает с ошибкой в том случае если изначально я хэширую в таком же алгоритме а не мд5. иначе ошибка "плохой хэш" - но я не уверен что мне нужна этафункция
SafeArrayBinПодписьДвоичная = КрПровайдер.SignData(SafeArrayBinХешДляПодписи, "SHA256"); - эта строка падает как неизвестная ошибка. Не могу понять почему. толи не так указываю алгоритм. толи еще почему то.
Подскажите какой из методов верный и какие параметры задать во втором методе.
ОТЛАДКА!
В студии написал код, отладил решение, а потом - прикрутил к 1с.
Кто помнить все типы и объекты КриптоAPI - тот и на 1с напишет.
Но не я.
По-существу вопроса1. ХЗ.
Получил ключ от яндекс навигатора. Подойдет ли данная обработка для этой задачи.???
Спасибо
Payload закодирован в base64url, а это отличается маленько от base64
Использовал вот такую функцию, найденную в соседней ветке
Функция Base64urlВСтроку(Знач СтрокаBase64)
Пока СтрДлина(СтрокаBase64) % 4 <> 0 Цикл
СтрокаBase64 = СтрокаBase64+ "=";
КонецЦикла;
СтрокаBase64 = СтрЗаменить(СтрокаBase64, "-", "+");
СтрокаBase64= СтрЗаменить(СтрокаBase64, "_", "/");
Возврат Base64Значение(СтрокаBase64);
КонецФункции ПоказатьВы можете заказать платную консультацию или разработку у автора. Будет создан приватный заказ на «Бирже заказов» для автора.
№ 896874
Создание 04.09.18 10:48
Обновление 24.10.18 19:55
Просмотры 42020
Загрузки 127
Рейтинг
28
Комментарии 100
Код открыт Да
Рубрики Разработка внешних компонент
Кому Разработчик
Тип файла Архив с данными
Платформа 1С:Предприятие 8
Конфигурация 1C:Бухгалтерия
Операционная система Windows
Страна Не имеет значения
Отрасль Не имеет значения
Налоги Не имеет значения
Вид учета Не имеет значения
Доступ к файлу Абонемент ($m)