|
v7: API честный знак | ☑ | ||
---|---|---|---|---|
0
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>) Я полагаю что я не авторизовался |
|||
1
Mafiozaa
15.02.21
✎
05:26
|
Я не совсем понял, но мне нужно полученные uuid и data отправить обратно подписаными?
|
|||
2
ДенисЧ
15.02.21
✎
05:32
|
А где у тебя в отправке вообще токен?
|
|||
3
Mafiozaa
15.02.21
✎
05:36
|
(2) Вот, собственно куда мне его толкнуть?
|
|||
4
big
15.02.21
✎
06:16
|
ДанныеЗапроса = Подписанные вашим ЭЦП данные;
ТекстЗапроса = "{""uuid"":"""+СокрЛП(СессияUuid)+""",""data"":""" + ДанныеЗапроса + """}"; Соеденение.Send(ТекстЗапроса); Примерно так. Но я давно с этим разбирался, вроде работало. |
|||
5
big
15.02.21
✎
06:17
|
(4) СессияUuid - это из запроса key полученной пары uuid/data
|
|||
6
lenkavovka
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); КонецЕсли; Результат = СтрЗаменить(Результат, Символы.ПС, ""); УдалитьФайлы(ИмяВременногоФайла); Возврат Результат; КонецФункции |
|||
7
Mafiozaa
15.02.21
✎
06:36
|
(6) Ну да, в 8ки я его загружаю в базу, а в 7ке надо ручками его цеплять, я так понял)
|
|||
8
lenkavovka
15.02.21
✎
06:43
|
(7) здесь ключевая идея - сначала получаем от ЧЗ некий uuid, потом включаем его в запрос токена, запрос подписываем своим сертификатом, запрашиваем токен. Посмотри внимательно на функцию ПодписатьТекст() во втором слайдере.
|
|||
9
Mafiozaa
15.02.21
✎
06:45
|
(8) Без руководства не разберусь, полез искать, спасибо)
|
|||
10
big
15.02.21
✎
06:55
|
(9) Получается ты вообще не в теме что-ли??
Воюшмать! (с) |
|||
11
big
15.02.21
✎
06:57
|
(10) Теперь понятно, что ответ на (2) был для него и не ответ в принципе ))))
|
|||
12
Mafiozaa
15.02.21
✎
06:59
|
(11) Ответ то ответ, я знаю что мне нужно полученное подписать и отправить далее, отправить отправлю, подписать нужно, буду искать вк на крипто
|
|||
13
big
15.02.21
✎
07:19
|
(12) В (6) уже всё есть, для подписывания в 7.7 не нужна ВК, хватает доступа к уже имеющимся объектам. В (3) вопрос был - куда токен воткнуть, вот и я показал )))
|
|||
14
Mafiozaa
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 |
|||
15
big
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"); РезСписок.ДобавитьЗначение(Отпечаток,Наименование+": "+ДатаКонец); КонецЦикла; Возврат РезСписок; КонецФункции |
|||
16
Mafiozaa
15.02.21
✎
07:52
|
(15) С CADESCOM почему то не идет, а CAPICOM показывает то же самое)
|
|||
17
big
15.02.21
✎
07:53
|
(16) КриптоПро ессно должен быть установлен.
|
|||
18
Mafiozaa
15.02.21
✎
07:53
|
(17) Все есть, все работает)
|
|||
19
Mafiozaa
15.02.21
✎
07:54
|
(17) С CADESCOM ругается на метод Open, якобы Поле агрегатного не обнаружено
|
|||
20
big
15.02.21
✎
07:54
|
(19) Хмм.. оччень странно.
|
|||
21
big
15.02.21
✎
07:59
|
(20) Прикол, но у меня тоже перестало работать (((
|
|||
22
Mafiozaa
15.02.21
✎
07:59
|
(20) CADESCOM = comStore.Open(
{C:\USERS\DMITRIY\DESKTOP\SQL-БАЗА\EXTFORMS\HTTP_ЗАПРОС.ERT(69)}: Поле агрегатного объекта не обнаружено (Open) CAPICOM = в цикле пробегаюсь получаю OLE.ICertificate2 я так думаю = колву моих сертификатов |
|||
23
big
15.02.21
✎
08:02
|
||||
24
big
15.02.21
✎
08:20
|
с CAPICOM работает.
|
|||
25
Mafiozaa
15.02.21
✎
08:52
|
(24) Вроде подразобрался малость, как мне выбрать сертификат которым подписывать?
|
|||
26
Mafiozaa
15.02.21
✎
08:52
|
(24) Из общей кучи, выбрать нужный
|
|||
27
big
15.02.21
✎
09:06
|
(25) А какой объект заработал? Cadescom или CAPICOM?
(26) Там же список, значение списка - отпечаток ключа, строка в списке - владелец + дата окончания. Выбирая из списка, получаешь отпечаток ключа, его подставляешь при подписывании. |
|||
28
Mafiozaa
15.02.21
✎
09:09
|
(24) РезСписок вижу, а просто список не вижу, такая же сз?
|
|||
29
Mafiozaa
15.02.21
✎
09:09
|
(27) И что за функция разложить субьъекта?
|
|||
30
big
15.02.21
✎
09:23
|
(25) А какой объект заработал? Cadescom или CAPICOM?
(26) Там же список, значение списка - отпечаток ключа, строка в списке - владелец + дата окончания. Выбирая из списка, получаешь отпечаток ключа, его подставляешь при подписывании. (29) Там просто из строки наименования берем названия, инн и т.п. Функция РазложитьСубъекта(Субъект) Результат = СоздатьОбъект("СписокЗначений"); Результат.ДобавитьЗначение(Субъект,"субъект"); ВремСтрока = СтрЗаменить(Субъект,",",РазделительСтрок); Для а=1 По СтрКоличествоСтрок(ВремСтрока) Цикл ТекСтр = СокрЛП(СтрПолучитьСтроку(ВремСтрока,а)); ТекСтр = СтрЗаменить(ТекСтр,"=",РазделительСтрок); Результат.ДобавитьЗначение(СокрЛП(СтрПолучитьСтроку(ТекСтр,2)),СокрЛП(СтрПолучитьСтроку(ТекСтр,1))); КонецЦикла; Возврат Результат; КонецФункции // гл |
|||
31
big
15.02.21
✎
09:23
|
(28) Да, просто выпадающий список на форме
|
|||
32
Mafiozaa
15.02.21
✎
09:25
|
(30) CAPICOM, но и то не все объекты подгружаются, щас буду смотреть
|
|||
33
Mafiozaa
15.02.21
✎
09:29
|
(31) Странно, ничего не попадает в список на форме
|
|||
34
Mafiozaa
15.02.21
✎
09:41
|
(31) Все попало, но нет наименования, а идет сразу D63489529FSDklsdfh23458sdklg
|
|||
35
big
15.02.21
✎
09:49
|
(34) скорее всего "разложение субъекта" некорректно работает
|
|||
36
Mafiozaa
15.02.21
✎
10:00
|
(35) Все, список эцп получаю корректно, мне как выбрать? обработку списка делать?
|
|||
37
big
15.02.21
✎
10:04
|
(36) Да как удобнее. Я при подписи просто беру текущий:
Отпечаток = СпсСертификатов.ПолучитьЗначение(СпсСертификатов.ТекущаяСтрока()); |
|||
38
Mafiozaa
15.02.21
✎
10:08
|
(37) А если не затруднит, покажешь как ты подписываешь текст?
|
|||
39
Mafiozaa
15.02.21
✎
10:19
|
(37) oSigner.Certificate = Отпечаток;
{C:\USERS\DMITRIY\DESKTOP\SQL-БАЗА\EXTFORMS\HTTP_ЗАПРОС.ERT(157)}: Типы не совпадают |
|||
40
Санта Клаус
15.02.21
✎
11:34
|
отмечусь, чтобы не потерять
|
|||
41
MWWRuza
гуру
15.02.21
✎
13:01
|
Я выкладывал обработку, которая из блока получает список пачек, под 7.7. Там все это есть. Ищите по слову "разагрегация"... А... Вот она кстати: http://catalog.mista.ru/public/1241751/
|
|||
42
DGorgoN
15.02.21
✎
13:04
|
(41) Тем паче помоги автору раз сталкивался.
|
|||
43
MWWRuza
гуру
15.02.21
✎
13:11
|
У меня там рабочий пример. Скачать, проверить, если заработает - то все нормально, можно "ковырять" и переносить в свою поделку фрагменты... Код открыт. А если не заработает - тогда нужно с КриптоПро, капикомом, сертификатами разбираться.
Будут конкретные вопросы, отвечу... Многие запустили, и работает, судя по комментариям. А уж как перенести из моей обработки в свою задачу, готовые, работающие алгоритмы, это только автору этой задачи ведомо... |
|||
44
Mafiozaa
18.02.21
✎
08:42
|
Поднимаю, ошибка та же
(37) oSigner.Certificate = Отпечаток; {C:\USERS\DMITRIY\DESKTOP\SQL-БАЗА\EXTFORMS\HTTP_ЗАПРОС.ERT(157)}: Типы не совпадают |
|||
45
oskarsan
06.06.21
✎
07:23
|
(44) тут нужен сертификат а не отпечаток
oSigner.Certificate = ПолучитьСертификатПоОтпечатку(Отпечаток); |
|||
46
Caesar
27.10.21
✎
17:23
|
Прошу прощения за подъем достаточно давней темы.
При попытке подписания токена получаю сообщение: sSignedMessage = oSignedData.SignCades(oSigner, CADESCOM_CADES_TYPE, bDetached, EncodingType); {E:\BASES\V7\КОВАЛЕВА СВЕРТКА\ОБМЕН_С_ЧЕСТНЫЙЗНАК.ERT(134)}: Поле агрегатного объекта не обнаружено (SignCades) Текст функции подписания - // bDetached - Истина/Ложь - откреплённая(для подписания документов)/прикреплённая(для получения токена авторизации) подпись Функция ПодписатьТекст(ТекстДляПодписи, СертификатДляПодписи, bDetached) //ТекстДляПодписи - токен в формате Base64 //СертификатДляПодписи - сертификат, полученный по отпечатку CADESCOM_BASE64_TO_BINARY = 1;// Входные данные пришли в Base64 CADESCOM_CADES_TYPE = 1;// Тип усовершенствованной подписи CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME = 0;// Атрибут штампа времени подписи oSigner = СоздатьОбъект("CAdESCOM.CPSigner"); // Объект, задающий параметры создания и содержащий информацию об усовершенствованной подписи. oSigner.Certificate = СертификатДляПодписи; //oSigner.KeyPin = "12345678";//пароль, с которым сертификат установлен на сервер. если пароля нет - комментируем строку oSigningTimeAttr = СоздатьОбъект("CAdESCOM.CPAttribute"); oSigningTimeAttr.Name = CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME; oSigningTimeAttr.Value = ТекущаяДата(); oSigner.AuthenticatedAttributes2.Add(oSigningTimeAttr); ТекстДляПодписи = СокрЛП(ТекстДляПодписи); oSignedData = СоздатьОбъект("CAdESCOM.CadesSignedData"); // Объект CadesSignedData предоставляет свойства и методы для работы с усовершенствованной подписью. oSignedData.ContentEncoding = CADESCOM_BASE64_TO_BINARY; oSignedData.Content = СокрЛП(ТекстДляПодписи); EncodingType = 0; sSignedMessage = oSignedData.SignCades(oSigner, CADESCOM_CADES_TYPE, bDetached, EncodingType); // ВОТ ТУТ ОШИБКА // Метод добавляет к сообщению усовершенствованную подпись. Возврат sSignedMessage;// Подпись в формате Base64 КонецФункции Цепочка сертификатов до доверенного КЦ выстроена. Очень прошу помочь. Заранее благодарен. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |