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

24.10.18

Разработка - Разработка внешних компонент

Внешняя компонента, исходники, обработка для 1С.

Скачать файлы

Наименование Файл Версия Размер
Обработка "все включено"
.epf 154,77Kb
57
.epf 154,77Kb 57 Скачать
Только внешняя компонента
.dll 8,00Kb
14
.dll 8,00Kb 14 Скачать
Windows приложение для тестирования функциональности
.exe 12,00Kb
12
.exe 12,00Kb 12 Скачать
Исходники
.zip 889,36Kb
16
.zip 889,36Kb 16 Скачать

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

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

 
 Юридическая информация

Когда мне была поставлена задача реализовать подписание ЭЦП по алгоритму 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 (встроена в фреймворк).
 
 Описание методов компоненты CoderEncoder.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 внешняя компонента

См. также

Медиадисплей. Рекламный информационный монитор для покупателя.

Разработка внешних компонент POS терминал Рабочее место Розничная торговля Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Управление торговлей 10 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Розничная и сетевая торговля (FMCG) Рестораны, кафе и фаст-фуд Реклама, PR и маркетинг Управленческий учет Платные (руб)

Монитор покупателя может отображать текущую покупку на кассовом месте, показывать видеорекламу, баннеры, во время простоя разворачивать рекламу на весь экран. Можно использовать в качестве графического меню-борда в кафе и видеовывески. Управление выводом на телевизор через hdmi-приставку на базе Windows или Android. В качестве устройства отображения можно использовать Android-планшеты, фоторамки с Android, монитор любого Windows-компьютера, доступного по сети. Настраивается ЛЮБОЙ ДИЗАЙН экрана!

16800 руб.

30.05.2017    52098    34    69    

43

Внешняя компонента для сканирования (замена TWAIN-компоненты БСП) (Native Win 32/64)

Разработка внешних компонент Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Внешняя компонента позволяет работать c TWAIN-совместимым оборудованием (сканерами, камерами) . Полностью совместима со стандартной TWAIN-компонентой из БСП и может применяться как ее замена без изменения вызовов, при этом может работать с 64-разрядной платформой, а так же имеет расширенную функциональность, например, сохранение результата непосредственно в PDF без использования сторонних утилит. Прекрасно работает на сервере, тонком клиенте и веб-клиенте (проверена работа в браузерах Google Chrome, Mozilla Firefox и Microsoft Internet Explorer).

2400 руб.

12.05.2020    26242    131    99    

83

Внешняя компонента для подключения 1С к телефонии Asterisk

Разработка внешних компонент Телефония, SIP Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

Внешняя компонента выполнена по технологии Native API для 1С 8.х, обеспечивает доступ к программным АТС Asterisk (FreePBX, Elastix) через AMI интерфейс. Через него можно управлять многими функциями Asterisk (определение номеров, перевод звонков, набор телефона и т. д.)

2400 руб.

04.05.2018    44974    117    64    

60

Внешняя компонента печати PDF (Native Win 32/64)

Разработка внешних компонент Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Внешняя компонента позволяет печатать PDF файлы непосредственно из 1С, не используя при этом сторонних программ. Прекрасно работает на сервере, тонком клиенте и веб-клиенте. Основана на проекте PDFium из состава проекта Chromium/Chrome

1500 руб.

17.09.2018    35075    104    123    

111

Мастер создания внешних компонент 1С (технология COM) для DELPHI 6/7/8/2005/2006/2007/2008/2010/XE/XE2/XE3

Разработка внешних компонент Платформа 1С v8.3 Платные (руб)

Средство для сверхбыстрой разработки внешних компонент 1С:Предприятия 7.7 и 8 по технологии COM на всех версиях DELPHI, начиная с 6.

2000 руб.

28.03.2013    53997    35    14    

68

QR-код с логотипом компании (обычная и управляемая форма)

Разработка внешних компонент Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Платные (руб)

Как известно, стремление сделать свою рекламную продукцию запоминающейся и выделяющейся — верный путь к успеху. Сегодня, мы поговорим с вами о том, что можно сделать с обычным черно-белым QR-кодом, чтобы он стал более живым и привлекательным. Если вам не терпится попробовать сделать QR-код с логотипом компании, то эта обработка для вас!

2400 руб.

22.06.2016    30839    4    4    

8

Внешняя компонента 1С и С++. Продолжаем разговор.

Разработка внешних компонент Платформа 1С v8.3 Бесплатно (free)

А давайте запилим 8.3.26 до релиза, или оповещение с сервера...

19.02.2024    4037    starik-2005    28    

52

Внешние компоненты 1С и язык C++

Разработка внешних компонент Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Некоторые практические аспекты создания внешних компонент на языке С++ для платформы 1С 8.3++.

26.01.2024    4774    starik-2005    32    

39
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. efin 04.09.18 11:20 Сейчас в теме
Спасибо за исходники!
Это большая редкость, когда автор не просто выкладывает бинарник (с х.з. каким кодом внутри), а дает возможность самому проверить код и собрать его.


У меня вопрос. Я вообще не владею .Net, и не люблю его (исторически сложилось).
Насколько проще/сложнее писать Native ВК для 1С на .Net, нежели на расово верном C++ (или хотя бы Dephi)?
softbear; +1 Ответить
4. astracrypt 75 04.09.18 12:46 Сейчас в теме
(1) Респект и уважуха автору.
5. Nikola23 696 04.09.18 16:19 Сейчас в теме
(1) пишите на чем можете. Вопрос "что проще" не считаю правильным.
36. uno-c 234 25.11.18 04:47 Сейчас в теме
(1)
Насколько проще/сложнее писать Native ВК для 1С на .Net, нежели на расово верном C++
На дотнете невозможно написать внешнюю компоненту для 1С по технологии Native.
37. Nikola23 696 25.11.18 18:48 Сейчас в теме
(36) Это является проблемой, только если Native - обязательно.
В моих задачах такого не встречал.
38. uno-c 234 25.11.18 19:21 Сейчас в теме
(37) Согласен. Но правильный ответ на конкретный вопрос "Насколько проще/сложнее писать Native ВК для 1С на .Net, нежели ..." звучит так: бесконечно сложнее, поскольку невозможно )
39. spacecraft 25.11.18 19:56 Сейчас в теме
(36)
На дотнете невозможно написать внешнюю компоненту для 1С по технологии Native.

"Да-да, конечно". Для некоторых это и правда невозможно.
https://habr.com/post/304542/?hl=ru_RU&fl=ru%2Cen
40. uno-c 234 25.11.18 20:14 Сейчас в теме
(39)Опять Вы невнимательны. В прошлый раз не заметили, что дотнет вызывает встроенного в ОС криптопровайдера, теперь не заметили, что в приведенном Вами примере по технологии Native на C++ написан враппер для классов дотнета. Т.е. для запуска скомпилированной дотнет dll-ки в приведенном примере нужна дополнительная компонента на неуправляемом коде, назвается она Native ВК. Но дотнетовская dll при этом не становится Native для 1С и без Native-прослойки на C++ не работает. Псевдокод в dll дотнета по определению не может быть внешней Native компонентой для 1С. Native должна быть написана на машинном коде.
41. spacecraft 25.11.18 21:40 Сейчас в теме
(40) вам шашечки или ехать? .NET библиотеки можно использовать в ВК Native.
Псевдокод в dll дотнета по определению не может быть внешней Native компонентой для 1С. Native должна быть написана на машинном коде.

С таким же успехом можно сказать, что любая программа на .NET не является программой, так как не написана на машинном коде.
42. uno-c 234 25.11.18 23:24 Сейчас в теме
(41)Тут да, вопрос терминологии. Любая программа на дотнете действительно не является исполняемой программой по определению. В практической плоскости это означает, что не получится скомпилировать дотнет-dll-ку для 1С , вставить ее в 1С в какой-нибудь двоичный макет, и запустить на паре-тройке других win-компьютеров без костылей. Например, в приведенном Вами примере автор предлагает для запуска тестовой dll-ки размером 70 килобайт - скачать и разместить в каталоге дополнительную многомегабайтную библиотеку.
43. uno-c 234 26.11.18 00:09 Сейчас в теме
(41)В чем вообще фишка Вашего примера? Предлагается взять скомпилированную на С++ AddInNetObjectToNative.dll - которая действительно является Native компонентой, туда же рядом скачать и поместить библиотеки NetCore, и только после этого скомпилированная из сишарпа NetObjectToNative.dll заработает. Тут два костыля получается. Это Вы называете созданием ВК по Native технологии для 1С на C#? Но если Вы обратите внимание на код 1С из Вашего примера, то единственная Native-ВК, которая там подключается - это ВК на С++
49. uno-c 234 28.11.18 04:40 Сейчас в теме
(41)
вам шашечки или ехать? .NET библиотеки можно использовать в ВК Native.
Только понял. Вы просто не уловили, о чем спрашивал saa@kuzov.org, когда писал "Насколько проще/сложнее писать Native ВК для 1С на .Net, нежели на расово верном C++ (или хотя бы Dephi)?" Если перефразировать - то он спрашивал "насколько сложнее написать Native на C#, чем на C++" или "насколько сложнее на Delphi чем на Visual Basic .NET", на это был мой ответ, который можно перефразировать "на языках дотнета написать Native невозможно". То, что библиотеки дотнета можно использовать через Native ВК, очевидно уже из разработки Nikola23, в рамках которой идет наше обсуждение. Но для этого, как и в Вашем примере, в эску сначала подключается Native на неуправляемом коде.
44. uno-c 234 26.11.18 10:00 Сейчас в теме
(39)
"Да-да, конечно". Для некоторых это и правда невозможно.
https://habr.com/post/304542/?hl=ru_RU&fl=ru%2Cen
Подытожим для ищущих способ написать на C# внешнюю Native компоненту для 1С. На сишарпе в принципе невозможно скомпилировать dll-ку, которая подключалась бы в 1С методом ПодключитьВнешнююКомпоненту("ИзСиШарпа.dll", "Имя", ТипВнешнейКомпоненты.Native). NativeВК из статьи по ссылке spacecraft-а написана на C++, в этом можно убедиться, если прочитать приведенную статью, обратить внимание на строки из нее
ИмяФайла=КаталогОтчета+"\AddInNetObjectToNative.dll";
ПодключитьВнешнююКомпоненту(ИмяФайла, "NetObjectToNative",ТипВнешнейКомпоненты.Native); 
и посмотреть исходники AddInNetObjectToNative.dll, любезно предоставленные автором упомянутой статьи.
45. Nikola23 696 27.11.18 06:08 Сейчас в теме
(44) Коллега, в чем суть вашего участия в обсуждении и того, как много времени вы тратите на доказывание своей правоты?

Мне вот все равно, правы Вы или нет. Просто интересно стало: у Вас много лишнего времени? Потратьте его на семью...

П,С, пока вы строчите комментарии я решаю задачи, пусть и не идеальным/оптимальным методом - я уже перерос юношеский максимализм.
С# использую, потому что знаю. С++ не знаю, учить не хочу, даже если на основы достаточно потратить 1 день.
46. uno-c 234 27.11.18 06:15 Сейчас в теме
(45)Искал когда-то сам ответы на эти вопросы, быстро не нашел, пополняю интернет правильными ответами. Жаль, что их портят некомпенетнтыми возражениями, но если польза будет возражающему, тогда не жаль. Пока Вы решаете чужие задачи, я занимаюсь чем хочу.
47. uno-c 234 27.11.18 06:51 Сейчас в теме
(45)А Вы скажите, в чем смысл шифрования в 1С с использованием двух костылей: C++ внешней компоненты плюс C# dll-ки? Именно шифрования, не подписи sha256rsa. Менеджер криптографии эсочный с шифрованием не справился?
48. uno-c 234 27.11.18 07:03 Сейчас в теме
(45)
С# использую, потому что знаю. С++ не знаю, учить не хочу, даже если на основы достаточно потратить 1 день.
Вы зря восприняли мою реплику про С++ в свой адрес. Она была предназначена для вопрошающего, который думал, что на языках дотнета можно написать NativeВК.
2. Steelvan 302 04.09.18 11:33 Сейчас в теме
Если сервера в Америке, то это будет самый большой риск для предпринимателя.
Заблокируют и будут шантажировать.
3. astracrypt 75 04.09.18 12:46 Сейчас в теме
(2) Это тебе не Раша, там уважают закон, никто без решения конгреса или постановления суда не будет тебя шантожировать.
6. Steelvan 302 04.09.18 22:24 Сейчас в теме
(3) Подотрите сопли, перестаньте верить в бабкины сказки и выучите правила грамматики русского языка.
И посмотри другие источники информации об Америке, кроме фильмов о супергероях.
CeHbKA; EmpireSer; +2 Ответить
75. dctvghbdtn 22.05.22 00:48 Сейчас в теме
(3) Наступил 2022 год ...
CeHbKA; Merkalov; Nikola23; +3 Ответить
7. echo77 1868 24.10.18 11:55 Сейчас в теме
(0) Классно!
Только поправьте заголовок на RSA-SHA256, а то поиском не ищется.
8. uno-c 234 11.11.18 10:11 Сейчас в теме
У меня криптопровайдер вшит в Windows, думаю у буржуев то же самое. Вот рабочий пример подписи RSA-SHA256 с его помощью на 1С. Закрытый ключ хранится в макете в виде xml, вспомогательные функции SafeИзДвоичных, ДвоичныеИзSafe и т.п. не привожу - понятно что они делают. Только что проверил - все работает, подпись рассчитывает, конечного получателя эта подпись устраивает.
Хеширование = Новый ХешированиеДанных(ХешФункция.SHA256);
Хеширование.Добавить(JWTдляСигнатуры);
Хеш = Хеширование.ХешСумма;

ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
ХМЛСертификатСЗакрытымКлючом = ОбработкаОбъект.ПолучитьМакет("Макет");
ХМЛТекст = ПолучитьСтрокуИзДвоичныхДанных(ХМЛСертификатСЗакрытымКлючом);
КрПровайдер = Новый COMОбъект("System.Security.Cryptography.RSACryptoServiceProvider");
КрПровайдер.FromXmlString(ХМЛТекст);

SafeArrayBinХешДляПодписи = SafeИзДвоичных(Хеш);
SafeArrayBinПодписьДвоичная = КрПровайдер.SignHash(SafeArrayBinХешДляПодписи, "SHA256");
ПодписьДвоичная = ДвоичныеИзSafe(SafeArrayBinПодписьДвоичная); 
Показать
DJ_Codebase; +1 Ответить
9. Nikola23 696 11.11.18 22:50 Сейчас в теме
(8) Раз за Вас. Спасибо за пример, может быть сообществу пригодится.
10. uno-c 234 12.11.18 00:07 Сейчас в теме
(9) Похоже, в статье вот это в заблуждение вводит:
Можно задействовать внешний криптопровайдер, но это стоит денег, да и сервер на котором все должно работать находится в Америке и там же админится, дадут ли устанавливать лишний софт – большой вопрос.
Криптопровайдер внешний не нужен, работает виндовский, без дополнительной оплаты.
11. uno-c 234 12.11.18 00:40 Сейчас в теме
(9) Более того, используемый Вами дотнет обращается к этому же виндовскому криптопровайдеру. Вы ведь в коде исходников не возводите хеш в степень закрытого ключа по модулю открытого ключа?
12. spacecraft 12.11.18 00:58 Сейчас в теме
(11)
Более того, используемый Вами дотнет обращается к этому же виндовскому криптопровайдеру

этот "виндовский криптопровайдер" не встроен в видну. Это библиотека того самого "дотнет" framework.

(10)
Криптопровайдер внешний не нужен, работает виндовский, без дополнительной оплаты.

Для приведенного примера да, не нужен. Намного интересней, когда понадобится использовать гостовский криптопровайдер.
14. uno-c 234 12.11.18 02:02 Сейчас в теме
(12)Во-первых, сам дотнет встроен в винду. Во-вторых, крипропровайдеры встроены в винду помимо дотнета. В третьих, в случае с RSA-SHA256 дотнет работает как оболочка для неуправляемого кода Microsoft Cryptography API (CryptoAPI), т.е. сам ничего не рассчитывает, а обращается API виндовского криптопровайдера, т.е. по сути делает то же самое, что я написал в коде 1С. Если в винде не будет нужного криптопровайдера - дотнет ничего не сможет с RSA-SHA256. А вот для случая с эллиптическими кривыми (например у ГОСТ такое) - там как раз да, дотнет сам все умеет вычислять в управляемом коде без обращения к CSP, т.е. по идее дотнету не нужен КриптоПро, хотя я так не пробовал, использовал cadescom.dll КриптоПрошный из 1С, он насколько помню бесплатный.
15. spacecraft 12.11.18 08:54 Сейчас в теме
(14)
Во-первых, сам дотнет встроен в винду.

Спорное утверждение. С точки зрения использования актуальной версии, ее приходится устанавливать как отдельное приложение.

(14)
В третьих, в случае с RSA-SHA256 дотнет работает как оболочка для неуправляемого кода Microsoft Cryptography API (CryptoAPI), т.е. сам ничего не рассчитывает, а обращается API виндовского криптопровайдера, т.е. по сути делает то же самое, что я написал в коде 1С. Если в винде не будет нужного криптопровайдера - дотнет ничего не сможет с RSA-SHA256.

Это в корне не верно. CryptoAPI это интерфейс, который как содержит свою реализацию криптопровайдера, так и может использовать сторонний. В данном случае System.Security.Cryptography.RSACryptoServiceProvider это сторонний криптопровайдер, который реализует интерфейс CryptoAPI. Т.е. это через CryptoAPI можно использовать криптопровайдер "дотнет".
16. uno-c 234 12.11.18 10:13 Сейчас в теме
(15)
С точки зрения использования актуальной версии, ее приходится устанавливать как отдельное приложение
Это как раз недостаток Вашего метода, поэтому метод напоминает причину отказа от операции Афенбаха из горячих голов.
Это в корне не верно
Читайте доки и смотрите свой код. "К именам неуправляемых реализаций обычно добавляется суффикс «CryptoServiceProvider» (скажем, SHA1CryptoServiceProvider), указывающий на то, что данная реализация на самом деле предоставляется криптопровайдером (Cryptographic Service Provider, CSP), который установлен на уровне операционной системы и действует как оболочка CryptoAPI. В имена управляемых реализаций включается суффикс «Managed» (например SHA1Managed). Такие реализации не опираются на CryptoAPI и содержат исключительно управляемый код." Ну и как Вас, Managed? ))
17. spacecraft 12.11.18 10:17 Сейчас в теме
(16) вы что-то попутали. Не я автор темы и никакого кода не выкладывал.
18. spacecraft 12.11.18 10:23 Сейчас в теме
(16) вы в самом деле не понимаете, что сами же в своем коде из 1С вызываете класс из библиотеки "дотнет"?
https://docs.microsoft.com/ru-ru/dotnet/api/system.security.cryptography.rsacryptoserviceprovider?view=netcore-2.0
19. uno-c 234 12.11.18 10:28 Сейчас в теме
(18)Похоже, Вы смотрите и не видите. Написано же, "предоставляемого поставщиком служб шифрования (CSP)" - т.е. дотнету нужен внешний криптопровайдер. В данном конкретном случае будет использоваться криптопровайдер винды по умолчанию - Microsoft Enhanced Cryptographic Provider или Microsoft Strong Cryptographic Provider. И где Вы в моих постах нашли утверждение, что мой код не использует класс дотнета? Я утверждал, что дотнет встроен в винду, криптопровайдер встроен в винду, и в данном случае дотнет использует бесплатный виндовский криптопровайдер. Это относилось к фразе автора
Можно задействовать внешний криптопровайдер, но это стоит денег
20. spacecraft 12.11.18 10:48 Сейчас в теме
(19) как это объясняет, что вы сами используете этот класс из 1С? "т.е. по сути делает то же самое, что я написал в коде 1С." По сути вы просто вызываете этот класс.
21. uno-c 234 12.11.18 11:04 Сейчас в теме
(20)Моему вызову не нужна конкретная версия дотнета, в отличие от разработки автора, если правильно понял Ваш вопрос. Я говорил платном криптопровайдере, который не нужен для RSA-SHA256, потому что встроен в винду и вызывается из дотнета.
22. spacecraft 12.11.18 11:16 Сейчас в теме
(21) тогда произошло недопонимание всех. Автор так же не использовал платный криптопровайдер, а воспользовался этим же встроенным классом из дотнет, только через ВК.
24. uno-c 234 12.11.18 17:04 Сейчас в теме
(22)а этот класс ничего не умеет кроме как обратиться к встроенному в винду Microsoft Enhanced Cryptographic Provider. Этот класс - просто обертка. В win-XP можно было достучаться к этому же криптопровайдеру через CAPICOM.
23. spacecraft 12.11.18 11:27 Сейчас в теме
(21) по сути, ваше решение подходит только для windows.
Решение с ВК может работать и на unix. Не знаю как сделано у автора, но теоретически это возможно.
Соответственно нужно использовать класс "System.Security.Cryptography.Algorithms".
25. uno-c 234 12.11.18 17:49 Сейчас в теме
(23)Похоже, что автор написал dll на управляемом коде и запускает ее с помощью native компоненты https://infostart.ru/public/300091/ Последняя сделана только для windows судя по описанию. Вот такой длинный путь вместо прямого обращения из кода 1С, как я предполагаю.
26. Nikola23 696 12.11.18 17:55 Сейчас в теме
(25) Что за холивар устроили Вы тут?
Компонента решает намного больше задач, чем просто создание цифровой подписи.

Но самое главное - не это. Полный интернет примеров кода, на всех языках, кроме 1с) Потому, какой пример (работающий) нашел, на том языке и скомпилил.

Напишите на 1с шифрование данных этим же алгоритмом. Уверен, сообществу будет благодарно.

Главное - не язык или технология, а решение задачи заказчика в рамках бюджета и сроков с приемлемым уровнем качества.
27. uno-c 234 12.11.18 18:22 Сейчас в теме
(26)Вам предложен более лаконичный способ решения Вашей задачи
реализовать подписание ЭЦП по алгоритму SHA256-rca
Плюс неплохо и пояснить spacecraft в чем он заблуждается, вдруг где пригодится. При чем тут холивар? Обратное тоже работает - spacecraft открывает для читающих что-то новое.
28. Nikola23 696 13.11.18 02:47 Сейчас в теме
(27) Предложен - ок, я поблагодарил сразу.
Только я не просил.

Оформите свои знания отдельной публикацией - сообщество поблагодарит...
29. uno-c 234 13.11.18 07:54 Сейчас в теме
(28)Ваша просьба не обязательна. Нашедший Ваше решение и прочитавший комментарии к нему увидит, что оно не оптимально. На отдельную статью приведенный мной способ сделать подпись RSA-SHA256 не тянет - в принципе в тех строчках кода, что я привел, и есть решение задачи, поставленной в начале Вашей статьи. Вот еще строчка - вариант проверки действительности цифровой подписи.
ПодписьВерна = КрПровайдер.VerifyHash (SafeArrayBinХешДляПодписи, "SHA256", SafeArrayBinПодписьДвоичная);
Асимметричное шифрование RSA - неактуально для 1С, но если будет нужно - принцип тот же.
30. Nikola23 696 13.11.18 21:49 Сейчас в теме
(29) По какому критерию оптимальность считаете?
31. uno-c 234 13.11.18 22:29 Сейчас в теме
(30) Эффективность по Парето. В данном случае выражается как "чем проще - тем лучше" при одинаковой функциональности. Хотя нет, функциональность в предложенном мной способе получше будет - нет завязки на версию дотнета. Ваше решение на win-10 потребует установки третьей версии дотнета.
32. Nikola23 696 14.11.18 09:38 Сейчас в теме
(31) Ваши утверждения высосаны из воздуха, что бы ваша позиция была подтверждена хоть чем-то. Конкретных цифр не предоставлено, да и вряд ли возможно, потому как Ваше решение - только куча слови и 3 строчки кода, на практике не проверялось. Не спорю, работать будет.

Лучшее решение - это то, которое решает задачу заказчика, в приемлемый срок с приемлемым качеством в рамках бюджета.

Коллега, уже не раз пишу, что функционал компоненты выходит за рамки создания ЭЦП. Почитайте описание хотя бы.
33. uno-c 234 14.11.18 10:34 Сейчас в теме
(32)Мое утверждение проверялось на Тинкофбанке при выдаче займов по схеме МФО, а также на 2LO авторизации Google API. Из двух решений, делающих одно и то же, лучшее то, которое менее требовательно к среде выполнения. Вы суть моего решения не поняли - делаете все то же самое, что у Вас написано и скомпилировано в dll, но делаете это напрямую из кода 1С, что подпись, что шифрование. И никаких dll и NETLoader при этом не нужно, работает на винде от 7 до 10 без запроса 3.5 дотнета - это из проверенного. На XP-sp3 тоже будет работать, если дотнет 35 поставить, на ранних XP даже с дотнетом 3.5 не работает, т.к. дотнет обращается к виндовому криптопровайдеру, а он в раньше не умел SHA256RSA. Добавлю из неочевидного к приведенному мной коду:
COMSafeArray = Новый COMSafeArray("VT_UI1", Байтов);//однобайтовый без знака
Он используется при передаче двоичных данных между эской и криптопровайдером.
34. Nikola23 696 14.11.18 10:45 Сейчас в теме
(33) Прошу за меня не решать, что я понял, а что нет.

Вы молодец, предлагаю перестать тешить свое ЧСВ, а сделать свои знания достоянием сообщества.
35. uno-c 234 14.11.18 10:56 Сейчас в теме
(34)Если кому-то нужно больше чем я написал, для решения задач подобной Вашей, без использования двух дополнительных dll-ок и без завязки на версию дотнет - вэлкам. Или помогу или действительно статью напишу. Что Вы поняли что нет - это не мое решение, а вывод из Ваших слов
Ваши утверждения высосаны из воздуха
Либо это из-за непонимания, либо еще хуже )
56. geniusan 06.11.19 17:03 Сейчас в теме
(35) Плюсую, сделал также для SHA512RSA. Пришлось сделать программку небольшую на C#, которая приватный ключ переводит из pfx в xml. Хранить его не очень безопасно получается в макете, пока сохранил в безопасном хранилище (от БСП), убрав все права у всех ролей, и сделав получение через привилегированный режим, но все равно - это ненадежно. В идеале бы найти способ, как можно средствами 1С, сертификат хранимый в хранилище сертификатов получить в xml, или как из него инициализировать RSACryptoServiceProvider.


Пример получения ЭЦП в 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), ""));
Показать
57. uno-c 234 06.11.19 19:55 Сейчас в теме
(56)Для перевода pfx в xml можно запустить PowerShell и скопипастить в него подобный скрипт:
$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"
Если Enter после последней строки не подхватите при копировании - дополнительно нажмите Enter в PowerShell

Для безопасного хранения закрытого ключа xml - можно зашифровать его средствами 1С:
	//шифруем ХМЛ
	МенеджерКриптографии = Новый МенеджерКриптографии("Microsoft Enhanced Cryptographic Provider v1.0","",1);
	ХранилищеСертификатов = МенеджерКриптографии.ПолучитьХранилищеСертификатов(ТипХранилищаСертификатовКриптографии.ПерсональныеСертификаты);
	Сертификат = ХранилищеСертификатов.НайтиПоОтпечатку(ПолучитьДвоичныеДанныеИзHexСтроки("908407f45198d4dd3a544c16d6b1a0cac85340cd"));
	ДвоичныеКлючаХМЛ = Новый ДвоичныеДанные("d:\UNSAFE\del\PrivateKey.xml");
	ДвоичныеЗашифрованногоХМЛ = МенеджерКриптографии.Зашифровать(ДвоичныеКлючаХМЛ, Сертификат);
	СтрокаЗашифрованныеХМЛ = Base64Строка(ДвоичныеЗашифрованногоХМЛ);
	
	//расшифровываем ХМЛ
	//МенеджерКриптографии.ПарольДоступаКЗакрытомуКлючу = "123";
	ДвоичныеЗашифрованногоХМЛ = Base64Значение(СтрокаЗашифрованныеХМЛ);
	ДвоичныеРасшифрованы = МенеджерКриптографии.Расшифровать(ДвоичныеЗашифрованногоХМЛ);
	СтрокаХМЛ = ПолучитьСтрокуИзДвоичныхДанных(ДвоичныеРасшифрованы);
	Сообщить(СтрокаХМЛ);
Показать
58. geniusan 07.11.19 00:57 Сейчас в теме
(57) Потрясающий ход :) Добавлю, пожалуй, шифрование/расшифровывание всего безопасного хранилища одним сертификатом. Не удивлюсь, если в БСП это тоже скоро допилят. Спасибо!
72. koln 27.08.21 10:00 Сейчас в теме
(56)У Вас в коде есть строка
BinaryЭЦП        = ОбъектШифрования.SignData_2(ДаныеБинарные, "2.16.840.1.101.3.4.2.3"); //SHA512RSA OUT:ComSafeArray
Откуда метод signdata_2? В документации по RSACryptoServiceProvider не нашел его. Там есть только signdata. И что означает второй параметр "2.16.840.1.101.3.4.2.3"?
61. user1113173 4 09.12.20 10:15 Сейчас в теме
(8) Здравствуйте. Дошел до такой же схемы, но возникает ошибка при выполнении метода SignHash, но я в параметре указывал просто ХешСумму. И в вашем комментарии нахожу решение. Подскажите что в функциях SafeИзДвоичных и ДвоичныеИзSafe?
62. uno-c 234 09.12.20 14:35 Сейчас в теме
(61) Здравствуйте! Вам нужен именно SignHash? Выше (56) приведен пример подписи сразу данных без отдельного вычисления хеша - т.е. сразу SignData. Мне отдельное хеширование нужно было, т.к. требовалось дополнительно сам хеш высылать - и раз уж хеш был готов - то я его SignHash-ил. А SignData все сам сделает - и хеш рассчитает какой попросите и подпишет (сам процесс RSA подписания включает в себя хеширование - т.к. подпись вычисляется на хеш). Единственное - SignData отдельно хеш Вам не выдаст, а только готовый результат - цифровую подпись.
user1113173; +1 Ответить
63. user1113173 4 09.12.20 14:47 Сейчас в теме
(62) ну я изначально хотел использовать МенеджерКриптографии для своей задачи, выпустил свой сертификат. Хешировал вручную, но как оказалось не могу использовать команду МенеджерКриптографии.Подписать, т.к. она еще и хеширует сама. А там нельзя выбрать SHA256. В итоге я пришел к использованию "RSACryptoServiceProvider". Мне хеш никуда отправлять не надо, но мне нужно захешировать 2 значения, строку с json кодом и спец. ключ, как сделать это в 1с я представляю, просто 2 раза прописать "добавить". Но как сделать это через SignData не представляю.
68. uno-c 234 09.12.20 16:18 Сейчас в теме
(63)Оставлю тут листинг на память. В его процессе производится цифровая подпись RSA-SHA256, и Гугл только что эту подпись успешно проверил.
&НаКлиенте
Процедура ТестГуглТаблица(Команда)
	ТестГуглТаблицаНаСервере();
КонецПроцедуры

&НаСервере
Процедура ТестГуглТаблицаНаСервере()
	
	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.
	//смотреть что нужно например: https://developers.google.com/sheets/api/guides/authorizing
	СтруктураДляЖсон.Вставить("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 https://www.googleapis.com/oauth2/v4/token.
	СтруктураДляЖсон.Вставить("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(сч));
	КонецЦикла;
	Возврат ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(Буфер);
КонецФункции

Показать
69. uno-c 234 10.12.20 08:26 Сейчас в теме
(68) Извините за дубль. Возможно, длинные посты как-то модерируются администрацией. Сначала я отправил (67) пост - но он не появился ни здесь ни на "Моя страница" - там где видны все мои посты в обратной хронологии. Я решил, что глюк в процессе отправки. Сделал (68) - но он снова не появился ни здесь ни на "Моя страница". А сегодня случайно заметил, что и на "Моя страница" все появилось, и здесь )
88. deman_ru 19 17.12.23 16:23 Сейчас в теме
(68)

ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
МакетЗакрытогоКлюча = ОбработкаОбъект.ПолучитьМакет("Макет");
ХМЛТекст = ПолучитьСтрокуИзДвоичныхДанных(МакетЗакрытогоКлюча);
КрПровайдер = Новый COMОбъект("System.Security.Cryptography.RSACryptoServiceProvider");
КрПровайдер.FromXmlString(ХМЛТекст);

SafeArrayBinХешДляПодписи = SafeИзДвоичных(Хеш);
SafeArrayBinПодписьДвоичная = КрПровайдер.SignHash(SafeArrayBinХешДляПодписи, "SHA256");
ПодписьДвоичная = ДвоичныеИзSafe(SafeArrayBinПодписьДвоичная);


Подскажите пожалуйста, подпись формируется открепленная или прикрепленная? Не нашел в описании RSACryptoServiceProvider параметр, который бы указывал на это.
89. uno-c 234 17.12.23 21:43 Сейчас в теме
(88) Открепленная. Тут смотрю вообще для готового хэша подпись вычисляется (SignHash), уже не помню с чем это было связано. Обычно подписываются исходные данные (SignData), при этом криптопровайдер сам все делает, сам хеширует и подписывает захешированное.
deman_ru; +1 Ответить
90. deman_ru 19 17.12.23 22:53 Сейчас в теме
(89) А возможно ли при помощи System.Security.Cryptography.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Строка(Подпись);
Показать


Не подскажите каким способом можно подписать исходные данные чтобы в итоге получилась прикрепленная подпись?
64. uno-c 234 09.12.20 14:55 Сейчас в теме
(61) Вот, вроде нашел.
&НаСервере
Функция SafeИзДвоичных(ДвоичныеДанные)
	Буфер = ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(ДвоичныеДанные);
	Байтов = Буфер.Размер;
	COMSafeArray = Новый COMSafeArray("VT_UI1", Байтов);//однобайтовый без знака
	Для сч = 0 по Байтов-1 Цикл
		COMSafeArray.SetValue(сч, Буфер.Получить(сч));
	КонецЦикла;
	Возврат COMSafeArray;
КонецФункции

&НаСервере
Функция ДвоичныеИзSafe(SafeArrayBin) 
	Буфер = Новый БуферДвоичныхДанных(SafeArrayBin.GetLength());
	Для сч = 0 по SafeArrayBin.GetUpperBound() Цикл
		Буфер.Установить(сч, SafeArrayBin.GetValue(сч));
	КонецЦикла;
	Возврат ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(Буфер);
КонецФункции
Показать
user1113173; +1 Ответить
65. user1113173 4 09.12.20 15:00 Сейчас в теме
(64) Спасибо большое. Удивительно что спустя 2 года у вас это сохранилось.
66. uno-c 234 09.12.20 15:04 Сейчас в теме
(65) Вам повезло, на самом деле я их полгода назад потерял вместе с полетевшим HDD, но сейчас Вы спросили - мысль появилась где еще поискать.
user1113173; +1 Ответить
67. uno-c 234 09.12.20 16:12 Сейчас в теме
(65) Оставлю тут листинг на память. Он пишет значение в гугл-таблицу, а что касается этой темы - перед записью идет получение токена, в процессе которого производится цифровая подпись по алгоритму RSA-SHA256 и Гугл проверяет подлинность этой подписи. Код рабочий, только что проверил - в ячейку гуглшита записалось 777999000. Где в коде xxxxx - в оригинале другие символы )
&НаКлиенте
Процедура ТестГуглТаблица(Команда)
	ТестГуглТаблицаНаСервере();
КонецПроцедуры

&НаСервере
Процедура ТестГуглТаблицаНаСервере()
	
	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.
	//смотреть что нужно например: https://developers.google.com/sheets/api/guides/authorizing
	СтруктураДляЖсон.Вставить("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 https://www.googleapis.com/oauth2/v4/token.
	СтруктураДляЖсон.Вставить("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(сч));
	КонецЦикла;
	Возврат ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(Буфер);
КонецФункции

Показать
user1113173; +1 Ответить
76. Mzhlskii 1 28.07.22 02:04 Сейчас в теме
(8)
ХМЛСертификатСЗакрытымКлючом

а какого вида у вас ХМЛСертификатСЗакрытымКлючом ?
77. uno-c 234 28.07.22 09:59 Сейчас в теме
(76) Можно взять из винды pfx и перевести его в xml как написано в 57 - на выходе получим файл xml
(57)
Mzhlskii; +1 Ответить
78. кольщик 09.12.22 14:10 Сейчас в теме
(8) Подскажите, а как в итоге получив подпись двоичную SHA256, подписать какой-нибудь файл?
С помощью Менеджера Криптографии делаю как в примере на ИТС:

Сертификат = Список[0];
Данные = ПолучитьИзВременногоХранилища(ПомещенныйФайл.Адрес);
МенеджерКриптографии = Новый МенеджерКриптографии("Microsoft Enhanced Cryptographic Provider v1.0", "", 1);
ИмяФайла = Ждать МенеджерКриптографии.ПодписатьАсинх(Данные, ПомещенныйФайл.СсылкаНаФайл.Файл.Путь + "Подписанный.p7s", Сертификат);
МенеджерКриптографии.ПарольДоступаКЗакрытомуКлючу = ПолучитьПарольДоступа();
ИмяФайла = Ждать МенеджерКриптографии.ПодписатьАсинх(Данные, ПомещенныйФайл.СсылкаНаФайл.Файл.Путь + "Подписанный.p7s", Сертификат);

Но тут же менеджер будет ругаться на тип провайдера, т.к. они не поддерживают SHA256.
79. uno-c 234 10.12.22 14:53 Сейчас в теме
(78) Раньше МенеджерКриптографии не умел делать подпись RSA-SHA256, хотя RSA-SHA1 умел. Видимо, до сих пор 256 не умеет.
80. кольщик 10.12.22 20:57 Сейчас в теме
(79) Да собственно так и не умеет.
Так описанным вами способом файл можно как-то подписать?
81. uno-c 234 10.12.22 21:12 Сейчас в теме
(80) Точно уже не помню что я подписывал. По логике если в COM делаем signHash - то вообще без разницы что подписывается, потому как в COM уже готовый хеш передается. А что там хешировали, строку или файл - это уже без разницы.
82. uno-c 234 10.12.22 21:29 Сейчас в теме
(80) Кроме того, насколько помню, мне еще и сам хеш нужен был, т.к. кроме подписи еще и хеш отправлялся. А если сам по себе хеш Вам не нужен, то в (56) сообщении более ускоренный вариант, не signHash, а сразу SignData. В примере в качестве данных передается хоть изначально и строка, но она перед этим преобразуется в COMSafeArray для передачи в COM

ДаныеБинарные = UTF8Encoding.GetBytes_4(ВходнаяСтрока); //ДаныеБинарные COMSafeArray

Это значит, что с тем же успехом можете двоичные данные файла преобразовать в COMSafeArray и передать их в COM на подпись (SignData). Смотрите (64) SafeИзДвоичных

Только обратите внимание, что в (56) SHA-512, а Вам нужен SHA-256
кольщик; +1 Ответить
83. кольщик 11.12.22 00:04 Сейчас в теме
(82) Круто. Спасибо! Пока правда каша в голове от перетеканий COM в SignData итд, но это уже теория)
84. кольщик 11.12.22 09:45 Сейчас в теме
(82) А еще не сориентируете, выполняю в powershel скрипт из (57) для перевода сертификата в xml.
Получаю ошибку на строке $myXml = $cert.PrivateKey.ToXmlString($True)
Нельзя вызвать метод для выражения со значением null.
Получается у меня с сертификатом что-то не то и он не определяется как объект? Или что может быть?
85. uno-c 234 11.12.22 14:13 Сейчас в теме
(84) Возможно, PrivateKey отсутствует
86. кольщик 13.12.22 00:10 Сейчас в теме
(85) Посмотрел, есть приваткей.
Уже на строках ругается:
$cert.Import($pat, $password, $flags)
$cert.GetRSAPrivateKey()

Сбой вызова метода из-за отсутствия в [System.Security.Cryptography.X509Certificates.X509Certificate2] метода с именем
"GetRSAPrivateKey".
13. uno-c 234 12.11.18 01:45 Сейчас в теме
50. stash_84 08.08.19 09:35 Сейчас в теме
(13) В связи с тем, что внутренние сообщения не работают, хотел бы тут обратиться к Вам - не могли бы Вы пояснить о своём решении, основанном на штатном криптопровайдере ОС?
51. Nikola23 696 08.08.19 22:31 Сейчас в теме
52. stash_84 09.08.19 07:04 Сейчас в теме
(51) вопрос был неверным - работа с криптографией средствами Крипто Про.
53. Nikola23 696 09.08.19 18:37 Сейчас в теме
(52) В этой компоненте крипто про не поддерживается. У крипто про есть свои методы.
54. stash_84 13.08.19 08:47 Сейчас в теме
(53) по этим методам есть подобные статьи или только на сайте "Крипто Про" необходимо брать документацию и разбираться?
55. Nikola23 696 13.08.19 21:06 Сейчас в теме
(54) Этот вопрос я не разбирал. Поэтому Вам надо самому разбираться. В т.ч. с поиском документации.
59. overclock 31.05.20 17:14 Сейчас в теме
Добрый день. Скачал отдельно библиотеку, хочу подключить ее через компоненту netloader.dll, используя CreateObjectFromFile, но там нужно указать класс. Подскажите его название.
ПодключитьВнешнююКомпоненту("ОбщийМакет.NETLoader", "NET") ;
Компонента = Новый("AddIn.NET.NETLoader");
Компонента.CreateObjectFromFile("C:\coderEncoder.dll", ???);
60. Nikola23 696 31.05.20 23:39 Сейчас в теме
(59) кто ж его помнит) Библитека с инфостарта - поищите по имени NetLoader.
А вообще в комментах к публикации есть описание решения на WinAPI без внешних компонент. Те же самые, фактически, методы, но без лишних оберток.
70. sakiselev 23.06.21 17:29 Сейчас в теме
может подскажите в чем ошибка или как правильно написать. Требуется данные захешировать в мд5. а потом подписать ключом с шифрованием sha256

sign = джейсон строка для подписи;

// получаем хэш мд5 в виде двоичных данных	
Хеш = Новый ХешированиеДанных(ХешФункция.MD5);
Хеш.Добавить(sign);
sign = Хеш.ХешСумма;
	
//подписываем	
	КрПровайдер = Новый COMОбъект("System.Security.Cryptography.RSACryptoServiceProvider");
	КрПровайдер.FromXmlString(ХМЛТекст);  //здесь хмл строка  приватного ключа
	
	SafeArrayBinХешДляПодписи = SafeИзДвоичных(sign);
Показать


//SafeArrayBinПодписьДвоичная = КрПровайдер.SignHash(SafeArrayBinХешДляПодписи, "SHA256"); - эта строка не падает с ошибкой в том случае если изначально я хэширую в таком же алгоритме а не мд5. иначе ошибка "плохой хэш" - но я не уверен что мне нужна этафункция

SafeArrayBinПодписьДвоичная = КрПровайдер.SignData(SafeArrayBinХешДляПодписи, "SHA256"); - эта строка падает как неизвестная ошибка. Не могу понять почему. толи не так указываю алгоритм. толи еще почему то.


Подскажите какой из методов верный и какие параметры задать во втором методе.
71. Nikola23 696 13.08.21 15:51 Сейчас в теме
(70) и тут я вспомнил, почему не стал кодить на 1с, а выбрал студию для этой задачи:
ОТЛАДКА!

В студии написал код, отладил решение, а потом - прикрутил к 1с.
Кто помнить все типы и объекты КриптоAPI - тот и на 1с напишет.
Но не я.

По-существу вопроса1. ХЗ.
73. RustikMsc 17.09.21 11:35 Сейчас в теме
А с ключем 4096 эта компонента будет работать?

Я с помощью openssl сгенерировал ключ
openssl genrsa -out privatekey.pem 4096

Мне необходимо подписать тело http запроса данным ключем
74. volga-autom 01.03.22 12:46 Сейчас в теме
Здравствуйте! Поставлена задача интегрировать яндекс навигатор с мобильным приложением. Есть инструкция по шифрованию строки которая передаются на мобильный клиент.
https://yandex.ru/dev/yandex-apps-launch/navigator/doc/concepts/navigator-commercial-use-signature.html

Получил ключ от яндекс навигатора. Подойдет ли данная обработка для этой задачи.???

Спасибо
87. ovas 11.12.23 13:20 Сейчас в теме
Здравствуйте! dll может подписывать приватным ключом?
deman_ru; +1 Ответить
Оставьте свое сообщение