Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 7.7 и ранее

v7: API честный знак

v7: API честный знак
Я
   Mafiozaa
 
15.02.21 - 05:24
Приветствую, получаю от Честного знака токен методом GET {"uuid":"d12b8e68-a2f8-48a2-sdcb-a3b632cbb270","data":"JLZTXJTMFXCXUUAFYQKHZOIQSAUXKC"}
    Соеденение = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
    Соеденение.Option(2,"utf-8");
    Соеденение.SetTimeouts(0,0,0,0);
    URL = "https://ismp.crpt.ru/api/v3/auth/cert/key";;
    Соеденение.Open("GET", URL, 0);
    Соеденение.SetRequestHeader("Content-Type", "application/json");
    Соеденение.SetRequestHeader("Accept-Charset", "utf-8");
    Соеденение.Send();
(Вот так получаю)

Мне для дальнейших действий я так понял, нужно его подписать и отправить методом POST
        Соеденение = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
    Соеденение.Option(2,"utf-8");
    Соеденение.SetTimeouts(0,0,0,0);
    URL = "https://ismp.crpt.ru/api/v3/auth/cert";;
    Соеденение.Open("POST", URL, 0);
    Соеденение.SetRequestHeader("Content-Type", "application/json");
    Соеденение.SetRequestHeader("Accept-Charset", "utf-8");
        Соеденение.Send();
    RequestTimeout = 40;
(Вот так отправляю, ошибка <UnauthorizedException><error>unauthorized</error><error_description>Full authentication is required to access this resource</error_description></UnauthorizedException>)
Я полагаю что я не авторизовался
   Mafiozaa
 
1 - 15.02.21 - 05:26
Я не совсем понял, но мне нужно полученные uuid и data отправить обратно подписаными?
   ДенисЧ
 
2 - 15.02.21 - 05:32
А где у тебя в отправке вообще токен?
   Mafiozaa
 
3 - 15.02.21 - 05:36
(2) Вот, собственно куда мне его толкнуть?
   big
 
4 - 15.02.21 - 06:16
ДанныеЗапроса = Подписанные вашим ЭЦП данные;
ТекстЗапроса = "{""uuid"":"""+СокрЛП(СессияUuid)+""",""data"":""" + ДанныеЗапроса + """}";

Соеденение.Send(ТекстЗапроса);


Примерно так. Но я давно с этим разбирался, вроде работало.
   big
 
5 - 15.02.21 - 06:17
(4) СессияUuid - это из запроса key полученной пары uuid/data
   lenkavovka
 
6 - 15.02.21 - 06:33
Приведу вымученный код для восьмёрки, чтобы было понимание, как разговаривать с ЧЗ. Предполагается, что сертификат ЭЦП, которым подписываем запросы, установлен на сервере и прописан в 1С, плюс прописан в настройках обмена с ИС МП:

&НаСервере
Функция ПолучитьТокен(Организация) Экспорт
    
    СертификатДляОбмена = ПолучитьСертификатОрганизацииИзНастроек(Организация);
    
    Если НЕ СертификатДляОбмена.Отпечаток = Неопределено Тогда
        
        Сертификат = НайтиСертификатПоОтпечаткуСтр(СертификатДляОбмена.Отпечаток);
        
        // Получение данных для получения токена

        HTTPСоединение =    Новый HTTPСоединение(ДанныеПодключенияЧестныйЗнак().АдресСервера, 443,,,,, Новый ЗащищенноеСоединениеOpenSSL);
        HTTPЗапрос = новый HTTPЗапрос("/api/v3/auth/cert/key");
        HTTPОтвет = HTTPСоединение.ВызватьHTTPМетод("GET", HTTPЗапрос);
        ОтветСтрока = HTTPОтвет.ПолучитьТелоКакСтроку("UTF-8"); 
        ЧтениеJSON = Новый ЧтениеJSON; 
        ЧтениеJSON.УстановитьСтроку(ОтветСтрока); 
        ДанныеJSON = ПрочитатьJSON(ЧтениеJSON); 
        ЧтениеJSON.Закрыть();
        УИД = ДанныеJSON.uuid;
        ДанныеДляПолученияТокена = ДанныеJSON.data;
        
        // Подписание данных для получения токена

        ДанныеДляПолученияТокена = ПодписатьТекст(ЗашифроватьBase64(ДанныеДляПолученияТокена, КодировкаТекста.UTF8), Сертификат, Ложь);
        
        // Получение токена с использованием подписанных данных

        Соединение = Новый HTTPСоединение(ДанныеПодключенияЧестныйЗнак().АдресСервера, 443,,,,, Новый ЗащищенноеСоединениеOpenSSL);
        Заголовки = Новый Соответствие;
        Заголовки.Вставить("Content-Type", "application/json; charset=UTF-8");
        Заголовки.Вставить("Accept", "application/json");
        HTTPЗапрос = Новый HTTPЗапрос("/api/v3/auth/cert/",Заголовки);
        ЗаписьJOIN = Новый ЗаписьJSON;
        ЗаписьJOIN.УстановитьСтроку();
        ДанныеДляЗапроса = Новый Структура;
        ДанныеДляЗапроса.Вставить("uuid",УИД);
        ДанныеДляЗапроса.Вставить("data",ДанныеДляПолученияТокена);    
        ЗаписатьJSON(ЗаписьJOIN,ДанныеДляЗапроса);
        СтрокаДляЗапроса = ЗаписьJOIN.Закрыть();
        
        HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаДляЗапроса,КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
        Ответ = Соединение.ОтправитьДляОбработки(HTTPЗапрос);
        Если Ответ.КодСостояния = 200 Тогда
            
            ЧтениеJSON = Новый ЧтениеJSON;
            ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
            
            Токен = ПрочитатьJSON(ЧтениеJSON, Ложь).token;
            
            Возврат Новый Структура("Токен, ТекстОшибки", Токен, "");
            
        Иначе
            
            Возврат Новый Структура("Токен, ТекстОшибки", Неопределено, "Ошибка получения токена. Код ответа: " + Ответ.КодСостояния + ".");    
        
        КонецЕсли;
        
    Иначе
        
        Возврат Новый Структура("Токен, ТекстОшибки", Неопределено, СертификатДляОбмена.ТекстОшибки);
        
    КонецЕсли;
    
КонецФункции



&НаСервере
Функция ПолучитьСертификатОрганизацииИзНастроек(Организация) Экспорт
    
    ХранилищеЗначения = Константы.НастройкиОбменаГосИС.Получить();
    СохраненныеНастройки = ХранилищеЗначения.Получить();
    
    НайденнаяСтрока = СохраненныеНастройки.Найти(Организация, "Организация");
    
    Если НайденнаяСтрока = Неопределено Тогда
        
        Отпечаток = Неопределено;
        ТекстОшибки = "Сертифкат для " + Организация + " не найден в настройках сертификатов для автоматического обмена с ИС МП";
                
    Иначе
        
        Отпечаток = НайденнаяСтрока.Сертификат.Отпечаток;
        ТекстОшибки = "";
        
    КонецЕсли;
    
    Возврат Новый Структура("Отпечаток, ТекстОшибки", Отпечаток, ТекстОшибки);
    
    
КонецФункции


&НаСервере
Функция НайтиСертификатПоОтпечаткуСтр(ОтпечатокСтр) Экспорт
    //Поиск доступных сертификатов

    CAPICOM_CURRENT_USER_STORE = 2;
    //2 - Искать сертификат в ветке "Личное" хранилища.

    CAPICOM_MY_STORE = "My";
    // Указываем, что ветку "Личное" берем из хранилища текущего пользователя

    CAPICOM_STORE_OPEN_READ_ONLY = 0;// Открыть хранилище только на чтение

    oStore = Новый COMОбъект("CAdESCOM.Store");// Объект описывает хранилище сертификатов

    
    oStore.Open(CAPICOM_CURRENT_USER_STORE, CAPICOM_MY_STORE,
    CAPICOM_STORE_OPEN_READ_ONLY);// Открыть хранилище сертификатов


    CAPICOM_CERTIFICATE_FIND_SHA1_HASH = 0;
    Certificates = oStore.Certificates.Find(CAPICOM_CERTIFICATE_FIND_SHA1_HASH, СтрЗаменить(Строка(Base64Значение(ОтпечатокСтр)), " ", ""));
    Возврат Certificates.Item(1);
КонецФункции


&НаСервере
// ТекстДляПодписи должен быть в Base64

// bDetached - Истина/Ложь - откреплённая(для подписания документов)/прикреплённая(для получения токена авторизации) подпись
Функция ПодписатьТекст(ТекстДляПодписи, Certificate, bDetached) Экспорт
    CADESCOM_BASE64_TO_BINARY = 1;// Входные данные пришли в Base64

    CADESCOM_CADES_TYPE = 1;// Тип усовершенствованной подписи

    CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME = 0;// Атрибут штампа времени подписи

    oSigner = Новый COMОбъект("CAdESCOM.CPSigner");
    // Объект, задающий параметры создания и содержащий информацию об усовершенствованной подписи.

    oSigner.Certificate = Certificate;
    oSigner.KeyPin = "123";//пароль, с которым сертификат установлен на сервер. если пароля нет - комментируем строку

    oSigningTimeAttr = Новый COMОбъект("CAdESCOM.CPAttribute");
    oSigningTimeAttr.Name = CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME;
    oSigningTimeAttr.Value = ТекущаяДата();
    oSigner.AuthenticatedAttributes2.Add(oSigningTimeAttr);
    ТекстДляПодписи = СокрЛП(ТекстДляПодписи);
    oSignedData = Новый COMОбъект("CAdESCOM.CadesSignedData");
    // Объект CadesSignedData предоставляет свойства и методы для работы с усовершенствованной подписью.

    oSignedData.ContentEncoding = CADESCOM_BASE64_TO_BINARY;
    oSignedData.Content = СокрЛП(ТекстДляПодписи);
    EncodingType = 0;
    sSignedMessage = oSignedData.SignCades(oSigner, CADESCOM_CADES_TYPE, bDetached, EncodingType);
    // Метод добавляет к сообщению усовершенствованную подпись.

    Возврат sSignedMessage;// Подпись в формате Base64

КонецФункции


&НаСервере
Функция ЗашифроватьBase64(Строка, Кодировка) Экспорт
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
    ЗаписьТекста = Новый ЗаписьТекста(ИмяВременногоФайла, Кодировка);
    ЗаписьТекста.Записать(Строка);
    ЗаписьТекста.Закрыть();
    Двоичные = Новый ДвоичныеДанные(ИмяВременногоФайла);
    Результат = Base64Строка(Двоичные);
    Если Лев(Результат, 4) = "77u/" Тогда
        Результат = Сред(Результат, 5);
    КонецЕсли; 
    Результат = СтрЗаменить(Результат, Символы.ПС, "");
    УдалитьФайлы(ИмяВременногоФайла);
    Возврат Результат;
КонецФункции
   Mafiozaa
 
7 - 15.02.21 - 06:36
(6) Ну да, в 8ки я его загружаю в базу, а в 7ке надо ручками его цеплять, я так понял)
   lenkavovka
 
8 - 15.02.21 - 06:43
(7) здесь ключевая идея - сначала получаем от ЧЗ некий uuid, потом включаем его в запрос токена, запрос подписываем своим сертификатом, запрашиваем токен. Посмотри внимательно на функцию ПодписатьТекст() во втором слайдере.
   Mafiozaa
 
9 - 15.02.21 - 06:45
(8) Без руководства не разберусь, полез искать, спасибо)
   big
 
10 - 15.02.21 - 06:55
(9) Получается ты вообще не в теме что-ли??

Воюшмать! (с)
   big
 
11 - 15.02.21 - 06:57
(10) Теперь понятно, что ответ на (2) был для него и не ответ в принципе ))))
   Mafiozaa
 
12 - 15.02.21 - 06:59
(11) Ответ то ответ, я знаю что мне нужно полученное подписать и отправить далее, отправить отправлю, подписать нужно, буду искать вк на крипто
   big
 
13 - 15.02.21 - 07:19
(12) В (6) уже всё есть, для подписывания в 7.7 не нужна ВК, хватает доступа к уже имеющимся объектам. В (3) вопрос был - куда токен воткнуть, вот и я показал )))
   Mafiozaa
 
14 - 15.02.21 - 07:30
(13) Прогнал, увидел вот это, я так полагаю это объекты моих сертификатов
OLE.ICertificate2
OLE.ICertificate2
OLE.ICertificate2
OLE.ICertificate2
OLE.ICertificate2
OLE.ICertificate2
OLE.ICertificate2
OLE.ICertificate2
OLE.ICertificate2
OLE.ICertificate2
OLE.ICertificate2
OLE.ICertificate2
OLE.ICertificate2
OLE.ICertificate2
OLE.ICertificate2
OLE.ICertificate2
OLE.ICertificate2
OLE.ICertificate2
OLE.ICertificate2
OLE.ICertificate2
   big
 
15 - 15.02.21 - 07:41
Функция ПолучитьСписокСертификатов()
    РезСписок    = СоздатьОбъект("СписокЗначений");
    comStore        = СоздатьОбъект("CAdESCOM.Store");
    comStore.Open(
        2,        // StoreLocation - CAPICOM_CURRENT_USER_STORE.

        "MY",    // StoreName

        );        // OpenMode - CAPICOM_STORE_OPEN_READ_ONLY.

    comCertificates = comStore.Certificates;
    comStore.Close();
    comStore = "";
    КоличествоСертификатов = comCertificates.Count;
    
    ТекДата    = ТекущаяДата();
    
    фл = 0;
    Для a=1 По КоличествоСертификатов Цикл
        Объект    = comCertificates.Item(a);
        
        Субъект        = Объект.SubjectName;
        ДатаНачало    = Объект.ValidFromDate;
        ДатаКонец    = Объект.ValidToDate;
        
        Если ДатаКонец < ТекДата Тогда
            Продолжить;
        КонецЕсли;
        Список    = РазложитьСубъекта(Субъект);
        ИНН        = Список.Получить("ИНН");
        Если ПустаяСтрока(ИНН) = 1 Тогда
            Продолжить;
        КонецЕсли;
        
        СерийныйНомер    = Объект.SerialNumber;
        Отпечаток        = Объект.Thumbprint;
        Наименование    = Список.Получить("CN");
        РезСписок.ДобавитьЗначение(Отпечаток,Наименование+": "+ДатаКонец);
    КонецЦикла;
    Возврат РезСписок;
КонецФункции
   Mafiozaa
 
16 - 15.02.21 - 07:52
(15) С CADESCOM почему то не идет, а CAPICOM показывает то же самое)
   big
 
17 - 15.02.21 - 07:53
(16) КриптоПро ессно должен быть установлен.
   Mafiozaa
 
18 - 15.02.21 - 07:53
(17) Все есть, все работает)
   Mafiozaa
 
19 - 15.02.21 - 07:54
(17) С CADESCOM ругается на метод Open, якобы Поле агрегатного не обнаружено
   big
 
20 - 15.02.21 - 07:54
(19) Хмм.. оччень странно.
   big
 
21 - 15.02.21 - 07:59
(20) Прикол, но у меня тоже перестало работать (((
   Mafiozaa
 
22 - 15.02.21 - 07:59
(20) CADESCOM = comStore.Open(
{C:\USERS\DMITRIY\DESKTOP\SQL-БАЗА\EXTFORMS\HTTP_ЗАПРОС.ERT(69)}: Поле агрегатного объекта не обнаружено (Open)
CAPICOM = в цикле пробегаюсь получаю OLE.ICertificate2 я так думаю = колву моих сертификатов
   big
 
23 - 15.02.21 - 08:02
   big
 
24 - 15.02.21 - 08:20
с CAPICOM работает.
   Mafiozaa
 
25 - 15.02.21 - 08:52
(24) Вроде подразобрался малость, как мне выбрать сертификат которым подписывать?
   Mafiozaa
 
26 - 15.02.21 - 08:52
(24) Из общей кучи, выбрать нужный
   big
 
27 - 15.02.21 - 09:06
(25) А какой объект заработал? Cadescom или CAPICOM?

(26) Там же список, значение списка - отпечаток ключа, строка в списке - владелец + дата окончания. Выбирая из списка, получаешь отпечаток ключа, его подставляешь при подписывании.
   Mafiozaa
 
28 - 15.02.21 - 09:09
(24) РезСписок вижу, а просто список не вижу, такая же сз?
   Mafiozaa
 
29 - 15.02.21 - 09:09
(27) И что за функция разложить субьъекта?
   big
 
30 - 15.02.21 - 09:23
(25) А какой объект заработал? Cadescom или CAPICOM?

(26) Там же список, значение списка - отпечаток ключа, строка в списке - владелец + дата окончания. Выбирая из списка, получаешь отпечаток ключа, его подставляешь при подписывании.

(29) Там просто из строки наименования берем названия, инн и т.п.

Функция РазложитьСубъекта(Субъект)
    Результат    = СоздатьОбъект("СписокЗначений");
    Результат.ДобавитьЗначение(Субъект,"субъект");
    
    ВремСтрока    = СтрЗаменить(Субъект,",",РазделительСтрок);
    Для а=1 По СтрКоличествоСтрок(ВремСтрока) Цикл
        ТекСтр    = СокрЛП(СтрПолучитьСтроку(ВремСтрока,а));
        ТекСтр    = СтрЗаменить(ТекСтр,"=",РазделительСтрок);
        Результат.ДобавитьЗначение(СокрЛП(СтрПолучитьСтроку(ТекСтр,2)),СокрЛП(СтрПолучитьСтроку(ТекСтр,1)));
    КонецЦикла;
    Возврат Результат;
КонецФункции// гл
 
 Рекламное место пустует
   big
 
31 - 15.02.21 - 09:23
(28) Да, просто выпадающий список на форме
   Mafiozaa
 
32 - 15.02.21 - 09:25
(30) CAPICOM, но и то не все объекты подгружаются, щас буду смотреть
   Mafiozaa
 
33 - 15.02.21 - 09:29
(31) Странно, ничего не попадает в список на форме
   Mafiozaa
 
34 - 15.02.21 - 09:41
(31) Все попало, но нет наименования, а идет сразу D63489529FSDklsdfh23458sdklg
   big
 
35 - 15.02.21 - 09:49
(34) скорее всего "разложение субъекта" некорректно работает
   Mafiozaa
 
36 - 15.02.21 - 10:00
(35) Все, список эцп получаю корректно, мне как выбрать? обработку списка делать?
   big
 
37 - 15.02.21 - 10:04
(36) Да как удобнее. Я при подписи просто беру текущий:
Отпечаток    = СпсСертификатов.ПолучитьЗначение(СпсСертификатов.ТекущаяСтрока());
   Mafiozaa
 
38 - 15.02.21 - 10:08
(37) А если не затруднит, покажешь как ты подписываешь текст?
   Mafiozaa
 
39 - 15.02.21 - 10:19
(37) oSigner.Certificate = Отпечаток;
{C:\USERS\DMITRIY\DESKTOP\SQL-БАЗА\EXTFORMS\HTTP_ЗАПРОС.ERT(157)}: Типы не совпадают
   Санта Клаус
 
40 - 15.02.21 - 11:34
отмечусь, чтобы не потерять
   MWWRuza
 
41 - 15.02.21 - 13:01
Я выкладывал обработку, которая из блока получает список пачек, под 7.7. Там все это есть.  Ищите по слову "разагрегация"... А... Вот она кстати: http://catalog.mista.ru/public/1241751/
   DGorgoN
 
42 - 15.02.21 - 13:04
(41) Тем паче помоги автору раз сталкивался.
   MWWRuza
 
43 - 15.02.21 - 13:11
У меня там рабочий пример. Скачать, проверить, если заработает - то все нормально, можно "ковырять" и переносить в свою поделку фрагменты... Код открыт. А если не заработает - тогда нужно с КриптоПро, капикомом, сертификатами разбираться.
Будут конкретные вопросы, отвечу... Многие запустили, и работает, судя по комментариям. А уж как перенести из моей обработки в свою задачу, готовые, работающие алгоритмы, это только автору этой задачи ведомо...
   Mafiozaa
 
44 - 18.02.21 - 08:42
Поднимаю, ошибка та же
(37) oSigner.Certificate = Отпечаток;
{C:\USERS\DMITRIY\DESKTOP\SQL-БАЗА\EXTFORMS\HTTP_ЗАПРОС.ERT(157)}: Типы не совпадают


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.