Api. Аутентификация в лк на основе подписи сертификата

1. Alexandryi 21.05.24 10:23 Сейчас в теме
Добрый день!
Подскажите, пытаюсь путем http api получать какую-либо информацию из лк Лк ПРСД

Проблема возникает уже на этапе подключения (ранее с api не сталкивался, первая попытка).

Из информации есть следующее:
Взаимодействие с системой Личный кабинет ПРСД осуществляется по протоколу HTTPS. Аутентификация пользователей производится на основе проверки цифровых подписей, сформированных при помощи сертификатов открытых ключей, зарегистрированных в системе Личный кабинет ПРСД. Цифровые подписи передаются через HTTP заголовок X-FRSD-Authentication

Точка входа API: https://lk.frsd.ru/xapi/


За основу пытался взять обработку https://infostart.ru/1c/tools/1414261/ , но безрезультатно. Кто шарит в теме, направьте на путь истинный.

АдресСервера = "lk.frsd.ru/xapi/";
АдресРесурса = "/xapi/";
ДвоичныеДанныеСертификата = Сертификат.ДанныеСертификата.Получить();
ИмяФайлаДанныеСертификата = ПолучитьимяВременногоФайла("cer");
ДвоичныеДанныеСертификата.Записать(ИмяФайлаДанныеСертификата);

ФайлДанныеСертификата = Новый Файл(ИмяФайлаДанныеСертификата);
РазмерФайлаДанныеСертификата = XMLСтрока(ФайлДанныеСертификата.Размер());

Заголовки = Новый Соответствие();
Заголовки.Вставить("POST " + АдресРесурса + " HTTP/1.1");
Заголовки.Вставить("Host", АдресСервера);
Заголовки.Вставить("X-FRSD-Authentication", ДвоичныеДанныеСертификата);

Запрос = Новый HTTPЗапрос(АдресРесурса, Заголовки);
Запрос.УстановитьИмяФайлаТела(ИмяФайлаДанныеСертификата);

ИмяВыходногоФайла = ПолучитьИмяВременногоФайла("txt");
Соединение = Новый HTTPСоединение(АдресСервера,,,,,, Новый ЗащищенноеСоединениеOpenSSL(), Ложь);
Ответ = Соединение.ОтправитьДляОбработки(Запрос, ИмяВыходногоФайла);
Показать
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. Hallucian 21.05.24 10:41 Сейчас в теме
(1)
Проблема возникает уже на этапе подключения

Выдаёт ошибку на Соединение?
3. user620512 21.05.24 12:21 Сейчас в теме
Для всех методов в заголовке X-FRSD-Authentication необходимо передать подпись url запроса в base64 формате.
Т.е. тебе надо строку закодировать в base64 и поместить в заголовок. Вот хороший пример как закодировать - https://forum.infostart.ru/forum9/topic136888/#message2165435

Как закодируешь то попробуй что то получить от сервиса, например

Получение списка документов.
GET /doc-list?od=${date}
Возвращает список документов в xml формате.


Пример запроса ниже, "результат" - "расшифрованный" ответ сервиса. Если где то накосячил, коллеги поправьте.

Заголовки = Новый Соответствие; 
Заголовки.Вставить("X-FRSD-Authentication", ЗакодированнаяСтрокаURLвBase64);

СоединениеHTTP = Новый HTTPСоединение("lk.frsd.ru",,,,,, Новый ЗащищенноеСоединениеOpenSSL);
HTTPЗапрос = Новый HTTPЗапрос("/xapi/doc-list?od>=2024-01-01", Заголовки);
HTTPОтвет = СоединениеHTTP.ВызватьHTTPМетод("GET", HTTPЗапрос);

КодОтвета = HTTPОтвет.КодСостояния;
Ответ = HTTPОтвет.ПолучитьТелоКакСтроку();

ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(Ответ);
Результат = ПрочитатьXML(ЧтениеXML);
ЧтениеXML.Закрыть();
Показать
5. Alexandryi 22.05.24 09:42 Сейчас в теме
(3) Спасибо за совет, попробовал:
	ДвоичныеДанныеСертификата = Сертификат.ДанныеСертификата.Получить();
	ИмяФайлаДанныеСертификата = ПолучитьимяВременногоФайла("cer");
	ДвоичныеДанныеСертификата.Записать(ИмяФайлаДанныеСертификата);
	
	ЗакодированнаяСтрокаURLвBase64 = Base64Строка(ДвоичныеДанныеСертификата); 
	
	Заголовки = Новый Соответствие; 
	Заголовки.Вставить("X-FRSD-Authentication", ЗакодированнаяСтрокаURLвBase64);

	СоединениеHTTP = Новый HTTPСоединение("lk.frsd.ru",,,,,, Новый ЗащищенноеСоединениеOpenSSL);
	HTTPЗапрос = Новый HTTPЗапрос("/xapi/doc-list?od>=2024-01-01", Заголовки);
	HTTPОтвет = СоединениеHTTP.ВызватьHTTPМетод("GET", HTTPЗапрос);

	КодОтвета = HTTPОтвет.КодСостояния;
	Ответ = HTTPОтвет.ПолучитьТелоКакСтроку();
	Сообщить (КодОтвета);
	
	ЧтениеXML = Новый ЧтениеXML;
	ЧтениеXML.УстановитьСтроку(Ответ);
	Результат = ПрочитатьXML(ЧтениеXML);
	ЧтениеXML.Закрыть();
Показать


В ответ село:
<!DO CTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HT ML><HEAD><TITLE>Bad Request</TITLE>
<MET A HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request - Invalid Header</h2>
<hr><p>HTTP Error 400. The request has an invalid header name.</p>
</BODY></HTML>
6. user620512 22.05.24 12:49 Сейчас в теме
(5) На заголовок ругается, тебе в (4) говорил serg33rus, что двоичные данные в заголовок не вставить, а ты похоже именно это и помещаешь в соответствие "Заголовки".
С подписями не работал, подсказать не смогу.
4. serg33rus 29 21.05.24 12:22 Сейчас в теме
Ну вообще-то там написано, что
Для всех методов в заголовке X-FRSD-Authentication необходимо передать подпись url запроса в base64 формате.

Т.е. как минимум подпись должна быть в base64. В заголовок воткнуть двоичные данные вообще невозможно.
Ну и вот эта фраза предусматривает передачу не сертификата, а подписи
Аутентификация пользователей производится на основе проверки цифровых подписей, сформированных при помощи сертификатов открытых ключей, зарегистрированных в системе Личный кабинет ПРСД. Цифровые подписи передаются через HTTP заголовок X-FRSD-Authentication
user1880116; +1 Ответить
7. Alexandryi 23.05.24 07:38 Сейчас в теме
(4) Добрый день!
Подскажите, нет ли примеров с передачей подписи сертификата?
8. serg33rus 29 23.05.24 17:28 Сейчас в теме
(7) Нет. С этой системой не работал, но фраза "Аутентификация пользователей производится на основе проверки цифровых подписей, сформированных при помощи сертификатов открытых ключей, зарегистрированных в системе Личный кабинет ПРСД"
Подразумевает, что передавать надо НЕ сертификат, а именно подпись. Т.е. сформировать подпись в ЛК при регистрации ключа. А потом именно эту подпись в base64 втыкать в header. Мне кажется что так.
В документации портала надо посмотреть внимательно как сформировать подпись.
9. user1880116 24.05.24 07:34 Сейчас в теме
(8)
Мне кажется что так.
Там же ясно написано: "передать подпись url запроса в base64 формате.", ты же это сам и приводил.

Берешь сертификат, грузишь в ЛК открытый ключ, у себя оставляешь закрытый. Когда тебе надо отправить запрос, берешь урл своего запроса, подписываешь своим закрытым ключем, полученное преобразуешь в base64 и вставляешь в заголовок. Отправляешь. На той стороне видят урл, видят подпись, проверяют ее при помощи открытого ключа, который ты загрузил в ЛК и убеждаются, что запрос отправлен действительно от тебя.
10. Alexandryi 24.05.24 07:59 Сейчас в теме
(9) На сайте у них размещен пример на c#, по отладчику пробежались работает он как вы и описали.
Создает пустой файл .dat, в него помещает строку"https://lk.frsd.ru/xapi/doc-list.xml?od=2024-05-23", этот файл подписывается закрытым ключом, и в итоге получается файл формата .dat.sgn. По итогу получаем xml файл со списком документов (ответ).

Но чз 1С так и не выходит авторизоваться. Последний вариант пробовали напрямую через файл, который получается в примере на c#, но тоже неверно, ошибка 401 ("Подпись запроса некорректна").
	ФайлСертификата = Новый ДвоичныеДанные("\\fs\1CBackUp\1.sgn");
	ФайлСертификатаBase64 = Base64Строка(ФайлСертификата);
	ФайлСертификатаBase64 = СтрЗаменить(ФайлСертификатаBase64, Символы.ВК, ""); 
	ФайлСертификатаBase64 = СтрЗаменить(ФайлСертификатаBase64, Символы.ПС, "");


	
	Заголовки = Новый Соответствие; 
	Заголовки.Вставить("X-FRSD-Authentication", ФайлСертификатаBase64);
	
	СоединениеHTTP = Новый HTTPСоединение("lk.frsd.ru",,,,,, Новый ЗащищенноеСоединениеOpenSSL());
	HTTPЗапрос = Новый HTTPЗапрос("/xapi/doc-list?od>=2024-05-23", Заголовки);
	HTTPОтвет = СоединениеHTTP.ВызватьHTTPМетод("GET", HTTPЗапрос);

	КодОтвета = HTTPОтвет.КодСостояния;
	Ответ = HTTPОтвет.ПолучитьТелоКакСтроку();
	Сообщить (Ответ);
	
	ЧтениеXML = Новый ЧтениеXML;
	ЧтениеXML.УстановитьСтроку(Ответ);
	Результат = ПрочитатьXML(ЧтениеXML);
	ЧтениеXML.Закрыть();
Показать
11. user1880116 24.05.24 10:55 Сейчас в теме
(10) У тебя урлы разные:
в него помещает строку"https://lk.frsd.ru/xapi/doc-list.xml?od=2024-05-23",
и
HTTPЗапрос = Новый HTTPЗапрос("/xapi/doc-list?od>=2024-05-23", Заголовки);
12. Alexandryi 24.05.24 13:11 Сейчас в теме
(11) Поменял, ну нет. Это запрос на получение списка документов, думаю допускается ">=" от даты.

Просмотрели, какая строка в base64 уходит из c#, и какая в 1С в переменной "ФайлСертификатаBase64" - строки идентичные.
Мб что-то с самим запросом неверно делаю..
13. user1880116 24.05.24 13:40 Сейчас в теме
(12)
думаю допускается
Ну, то есть ты подписываешь одну строку урл, а посылаешь другую. Но с подписью от первой. Ясно. Понятно. Что-же может пойти не так?
Alexandryi; +1 Ответить
14. Alexandryi 24.05.24 14:23 Сейчас в теме
(13) Спасибо, направили на верную мысль. В запросе 1С не было ".xml". Дописал, ответ получил)
Теперь нужно такой файл с подписью средствами 1С получить.

Подписать любой файл пробовал через МенеджерКриптографии - работает.
Можно будет создать текстовый файл, заполнить строкой запроса и подписать, но верный ли путь это будет? Или получится, что подгоняю под вариант из C# и есть другие пути?
15. user1880116 24.05.24 20:16 Сейчас в теме
(14)
создать текстовый файл
Насколько я помню, метод Подписать менеджера криптографии возвращает двоичные данные подписи сразу, так что можно обойтись без файла. Посмотри в синтакс-помощнике.
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот