Форум OlegON > Программы и оборудование для автоматизации торговли > Маркировка

Как программно подписать данные УКЭП

05.08.2020 20:22


20.02.2020 05:42
Yurgis
 
Никогда не сталкивался с этой напастью.
Есть "алкогольные" рутокены и джакарты, желание подписать данные УКЭП для авторизации у "оператора маркировки", и полное непонимание, как это сделать.
1. Можно ли для этого вообще использовать рутокен с "алкогольными" сертификатами, или надо что-то другое ?
2. Можно ли воспользоваться Rutoken API, или КриптоПро API, или еще чем-то ?
3. Как прицепить отдельно сгенерированную электронную подпись к исходным данным?
4. "Усиленная" и "Усовершенствованная" КЗП -- это одно и то же?
Поделитесь, пожалуйста, опытом, а то голова уже раздулась.
20.02.2020 10:58
George
 
Спасибо за ответ. Но спросить я хотел про то, как подписать данные ПРОГРАММНО. Из программного кода, то есть. Не из браузера или Wordа. Какой API лучше использовать для подписания, обязательно ли перед этим хешировать данные, если они и так короткие, как слепить данные с УКЭП, если УКЭП формируется отдельно, как "усилить" КЭП и т.д. Просто документация по API криптосистем труднопостижима, поскольку написана для тех, кто и так уже все это знает.
20.02.2020 11:01
baggio
 
Что значит подписать данные?
Что вы имеете ввиду говоря данные?
20.02.2020 11:11
George
 
Имею в виду "массив случайных данных", который надо запросить в ИС МП и подписать моей УКЭП, чтобы получить аутентификационный токен (Цитирую по "ИС МП. Описание API V.2.2.0")
20.02.2020 11:24
George
 
Извините, забыл уточнить. Речь идет об авторизации в системе Оператора маркировки через его API.
20.02.2020 11:34
baggio
 
Цитата:
George Имею в виду "массив случайных данных",
тут мои полномочия все.... хз что это...
20.02.2020 11:51
MWWRuza
 
Цитата:
George Имею в виду "массив случайных данных", который надо запросить в ИС МП и подписать моей УКЭП,
Код под 1с7.7 пойдет? Разберетесь? Потом уже "перелопатите" под свою среду разработки...
Могу выложить.
20.02.2020 11:58
George
 
Спасибо. Было бы здорово.
20.02.2020 12:05
MWWRuza
 
Вот тут не все функции, например, нужна функция "глРазборJSON" (они просто часть моей конфигурации, уже давно, это надо их оттуда "выковыривать"), я не могу гарантировать, что у Вас это в таком виде "заведется", но принцип понять можно:

// sThumbprint - отпечаток сертификата, используемого для подписи; строка, представляющая отпечаток в шестандцатеричном виде
Функция ПодписатьТекст(ТекстДляПодписи, sThumbprint,БезBOM=1)

infile = КаталогВременныхФайлов()+"infile.txt";
Если ФС.СуществуетФайл(infile) = 1 Тогда
Попытка
ФС.УдалитьФайл(infile);
Исключение
infile = КаталогВременныхФайлов() + "infile" + ГенераторGIUD() + ".txt";
КонецПопытки;
КонецЕсли;
outfile = КаталогВременныхФайлов()+"outfile.txt";
Если ФС.СуществуетФайл(outfile) = 1 Тогда
Попытка
ФС.УдалитьФайл(outfile);
Исключение
outfile = КаталогВременныхФайлов() + "outfile" + ГенераторGIUD() + ".txt";
КонецПопытки;
КонецЕсли;
Если Прав(ТекстДляПодписи,4) = ".xml" Тогда
infile = ТекстДляПодписи;
ПодписатьФайл(infile,ПолучитьСертификатПоОтпечатку(sThumbprint),outfile);
Если ФС.СуществуетФайл(outfile) = 1 Тогда
Возврат outfile;
Иначе
Возврат "";
КонецЕсли;
Иначе
Если БезBOM = 1 Тогда
ВремТекст = СоздатьОбъект("Текст");
ВремТекст.ДобавитьСтроку(ТекстДляПодписи);
ВремТекст.Записать(infile);
Иначе
АдоДБСтрим = СоздатьОбъект("ADODB.Stream");
АдоДБСтрим.Mode = 3;
АдоДБСтрим.Type = 2;//текст
АдоДБСтрим.charset="utf-8";
АдоДБСтрим.Open();
АдоДБСтрим.WriteText(ТекстДляПодписи);
АдоДБСтрим.Position=0;
АдоДБСтрим.SaveToFile(infile,2);
АдоДБСтрим.Close();
КонецЕсли;
ПодписатьФайл(infile,ПолучитьСертификатПоОтпечатку(sThumbprint),outfile);
Если ФС.СуществуетФайл(outfile) = 1 Тогда
Возврат outfile;
Иначе
Возврат "";
КонецЕсли;
КонецЕсли;
КонецФункции

//******************************************************************************
// ПолучитьPublic_cert(ПутьКСертификату)
//
// Параметры:
// ПутьКСертификату - путь к файлу или текст сертификата КЭП
//
// Возвращаемое значение:
// public_cert,signature
//
// Описание:
// убирает переносы строк и возвращает содержимое в виде строки
//
Функция ПолучитьPublic_cert(ПутьКСертификату)

ВозврPublic_cert = "";
Если (Прав(ПутьКСертификату,4) = ".cer") ИЛИ (Прав(ПутьКСертификату,4) = ".txt") Тогда
Если ФС.СуществуетФайл(ПутьКСертификату) = 0 Тогда
Сообщить("Файл сертификата "+СокрЛП(ПутьКСертификату)+" не найден");
Возврат "";
КонецЕсли;
АдоДБСтрим = СоздатьОбъект("ADODB.Stream");
АдоДБСтрим.Mode = 3;
АдоДБСтрим.Type = 2;//текст
АдоДБСтрим.charset="utf-8";
АдоДБСтрим.Open();
АдоДБСтрим.LoadFromFile(ПутьКСертификату);
АдоДБСтрим.Position = 0;
ТекстСертификата = АдоДБСтрим.ReadText(-1);
АдоДБСтрим.Close();
Для СчСтрок = 1 По СтрКоличествоСтрок(ТекстСертификата) Цикл
ТекСтрока = СтрПолучитьСтроку(ТекстСертификата,СчСтрок);
Если Лев(ТекСтрока,4) = "----" Тогда
Продолжить;
КонецЕсли;
ТекСтрока = СтрЗаменить(ТекСтрока,РазделительСтрок,"");
ВозврPublic_cert = ВозврPublic_cert + ТекСтрока;
КонецЦикла;
Иначе
Для СчСтрок = 1 По СтрКоличествоСтрок(ПутьКСертификату) Цикл
ТекСтрока = СтрПолучитьСтроку(ПутьКСертификату,СчСтрок);
Если Лев(ТекСтрока,4) = "----" Тогда
Продолжить;
КонецЕсли;
ТекСтрока = СтрЗаменить(ТекСтрока,РазделительСтрок,"");
ВозврPublic_cert = ВозврPublic_cert + ТекСтрока;
КонецЦикла;
КонецЕсли;
Возврат ВозврPublic_cert;
КонецФункции // ПолучитьPublic_cert()

// Возвращает пары идентификатор-данные для запроса токена
Функция ВернутьПаруЗапрТокена(УРЛ, ПрефиксВерсии)
// WinHttp = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
WinHttp.Option(2,"utf-8");
WinHttp.SetTimeouts(0, 0, 0, 0);
Url = "https://" + УРЛ + ПрефиксВерсии + "auth/cert/key";
WinHttp.Open("GET", Url, 1);
WinHttp.SetRequestHeader("Content-Type", "application/json");
WinHttp.SetRequestHeader("Accept-Charset", "utf-8");
WinHttp.Send();
RequestTimeout = 40;
Попытка
Рез = WinHttp.WaitForResponse(RequestTimeout);
Исключение
Рез = 0;
Ответ = ОписаниеОшибки();
КонецПопытки;
Ответ = "";
Если Рез = -1 Тогда
Статус = WinHttp.status();
Ответ = СокрЛП(WinHttp.ResponseText());
КонецЕсли;
СЗ = глРазборJSON(Ответ);
Возврат СЗ;
КонецФункции

// Параметры:
// code
// Возвращаемое значение:
// token
//
// Описание:
Функция ПолучитьТокенЦРПТ(ВыбЭЦП, ПрефиксВерсии, СтрОшибка="",life_time=0) Экспорт
Перем Сигнатура;
Перем uuid;
Перем code;
СзКей = ВернутьПаруЗапрТокена(СокрЛП(Константа.АдресСервисаМОТП), ПрефиксВерсии);
сзJSONЗапрос = СоздатьОбъект("СписокЗначений");
Сч = 0;
Для Сч = 1 По СзКей.РазмерСписка() Цикл
uuid = СзКей.Получить("uuid");
code = СзКей.Получить("data");
Сигнатура = ПодписатьТекст(code,СокрЛП(ВыбЭЦП.Отпечаток),1);
Если ПустоеЗначение(Сигнатура) = 1 Тогда
Возврат "";
КонецЕсли;
Сигнатура = ПолучитьPublic_cert(Сигнатура);
сзJSONЗапрос.Установить("uuid",uuid);
сзJSONЗапрос.Установить("data",Сигнатура);
КонецЦикла;
Ответ = глHTPP_ВыполнитьЗапрос("POST","https://" + СокрЛП(Константа.АдресСервисаМОТП) + ПрефиксВерсии + "auth/cert/", сзJSONЗапрос,,,СтрОшибка);
Если ПустоеЗначение(Ответ) = 0 Тогда
сзОтвет = глРазборJSON(Ответ);
КонецЕсли;
Если ПустоеЗначение(сзОтвет) = 1 Тогда
Возврат 0;
КонецЕсли;
Возврат сзОтвет.Получить("token");
КонецФункции // ПолучитьКлючСессии()

PS Функции подписания - не мои, пришлось "по крупицам" собирать на ИнфоСтарте, Мисте, и т.д...

Форум на базе vBulletin®
Copyright © Jelsoft Enterprises Ltd.
В случае заимствования информации гипертекстовая индексируемая ссылка на Форум обязательна.