Как получить авторизационный токен Диадок в 1С и исправить ошибку десериализации сертификата?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При настройке интеграции с сервисом Диадок через HTTP-запросы разработчики часто сталкиваются с ошибкой 400 Bad Request и сообщением сервера "Could not deserialize certificate from the request body". Эта проблема возникает на этапе получения первичного авторизационного токена, когда сервер не может корректно распознать переданные данные сертификата. В рамках данной статьи мы подробно разберем, как правильно сформировать запрос, обработать двоичные данные и учесть особенности современных криптопровайдеров.

Анализируем причины возникновения ошибки 400

Для начала проанализируем ситуацию: сервер Диадок ожидает в теле POST-запроса сырые двоичные данные сертификата в формате X.509 (DER-кодировка). Если сервер возвращает ошибку десериализации, это означает, что данные пришли в искаженном виде или формат HTTP-пакета нарушен. Рассмотрим основные ошибки, которые допускаются в коде 1С:

  1. Лишние данные в заголовках: Часто программисты вручную добавляют в объект HTTPЗапрос строку вида "POST /v3/Authenticate... HTTP/1.1". Если вы только учитесь работать с протоколом, рекомендуем пройти интерактивный обучающий курс по HTTP-запросам. Этого делать нельзя, так как метод ОтправитьДляОбработки() формирует стартовую строку автоматически.
  2. Неправильный Content-Length: Ручная установка длины контента может не совпадать с реальным размером двоичных данных сертификата. Проверить корректность отправки можно через инструменты тестирования http-сервисов.
  3. Искажение при чтении ответа: Попытка прочитать двоичный ответ сервера как текст через Ответ.ПолучитьТекст() приводит к потере спецсимволов.
  4. Устаревший тип криптопровайдера: Использование типа 75 (ГОСТ 2001) вместо 80 (ГОСТ 2012) для новых сертификатов.

Шаг 1. Получение сертификата в правильном формате

Для взаимодействия с API нам необходимо выгрузить сертификат из хранилища в виде двоичных данных. Важно использовать актуальный МенеджерКриптографии. Разберем пример получения сертификата:


// Определяем тип провайдера: 80 соответствует ГОСТ Р 34.10-2012
ТипПровайдера = 80; 
ИмяПровайдера = "Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider";

Менеджер = Новый МенеджерКриптографии(ИмяПровайдера, "", ТипПровайдера);
Менеджер.ПарольДоступа = "ВашПароль"; // Если требуется

Хранилище = Менеджер.ПолучитьХранилищеСертификатов(
    ТипХранилищаСертификатовКриптографии.ПерсональныеСертификаты,
    РасположениеХранилищаСертификатовКриптографии.ДанныеКомпьютера
);

Сертификаты = Хранилище.ПолучитьВсе();
// В реальной задаче нужно найти сертификат по отпечатку (Thumbprint)
Сертификат = Сертификаты[0]; 
ДанныеСертификата = Сертификат.Выгрузить(); 

Метод Выгрузить() возвращает объект ДвоичныеДанные, который содержит структуру сертификата X.509. Именно эти данные мы будем передавать в теле запроса.

Шаг 2. Настройка HTTP-соединения и формирование запроса

Теперь выясним причину проблем с заголовками. Рассмотрим правильный способ подготовки объекта HTTPЗапрос. Обратите внимание, что мы не устанавливаем Host и Content-Length вручную.


Сервер = "diadoc-api.kontur.ru";
// Используем v3 для соответствия современным требованиям безопасности
АдресРесурса = "/v3/Authenticate?type=certificate"; 

Соединение = Новый HTTPСоединение(Сервер, , , , , 30, Новый ЗащищенноеСоединениеOpenSSL());

Запрос = Новый HTTPЗапрос(АдресРесурса);
Запрос.Заголовки.Вставить("Authorization", "DiadocAuth ddauth_api_client_id=" + КлючРазработчика);
Запрос.Заголовки.Вставить("Content-Type", "application/octet-stream");
Запрос.Заголовки.Вставить("Accept", "application/json");

// Устанавливаем тело запроса напрямую из двоичных данных сертификата
Запрос.УстановитьТелоИзДвоичныхДанных(ДанныеСертификата);

Ответ = Соединение.ОтправитьДляОбработки(Запрос);

Шаг 3. Двухэтапная авторизация (v3)

Проанализируем важный нюанс: API версии v3 работает в два этапа. Просто получить ответ недостаточно. На первом этапе сервер возвращает зашифрованное временное "сообщение" (челлендж), которое нужно расшифровать вашим закрытым ключом и отправить обратно.

Этап расшифровки: Полученные от сервера данные на первом шаге — это зашифрованный массив байтов. Мы должны использовать метод Расшифровать() объекта МенеджерКриптографии.


Если Ответ.КодСостояния = 200 Тогда
    // Получаем тело ответа ТОЛЬКО как двоичные данные
    ЗашифрованныеДанные = Ответ.ПолучитьТелоКакДвоичныеДанные();
    
    Попытка
        // Расшифровываем данные закрытым ключом сертификата
        РасшифрованныеДанные = Менеджер.Расшифровать(ЗашифрованныеДанные);
        
        // Теперь расшифрованные данные нужно отправить на /v3/AuthenticateConfirm
        // Аналогичным образом формируем второй POST-запрос
        ЗапросПодтверждения = Новый HTTPЗапрос("/v3/AuthenticateConfirm");
        ЗапросПодтверждения.Заголовки.Вставить("Authorization", "DiadocAuth ddauth_api_client_id=" + КлючРазработчика);
        ЗапросПодтверждения.УстановитьТелоИзДвоичныхДанных(РасшифрованныеДанные);
        
        ОтветТокен = Соединение.ОтправитьДляОбработки(ЗапросПодтверждения);
        Если ОтветТокен.КодСостояния = 200 Тогда
            Токен = ОтветТокен.ПолучитьТелоКакСтроку();
            Сообщить("Авторизация успешна! Токен получен.");
        КонецЕсли;
    Исключение
        Сообщить("Ошибка расшифровки: " + ОписаниеОшибки());
    КонецПопытки;
КонецЕсли;

Подведем итоги: важные моменты

Подводя итог, выделим ключевые правила работы с API Диадок в 1С:

Соблюдение этих правил позволит вам избежать ошибки десериализации и успешно настроить обмен электронными документами через прямое API Диадок.

← На главную