Синхронно: attached/detached и реальные сертификаты CMS/получателя AES

Учебные задачи

Полный собственный опыт для новых с8.3.24 методов: получает actual CMS detached/attached, определяет наличие payload, извлекает точный DER и разыменует получателя собственного зашифрованного envelope через свой My. Не называет парсинг проверкой подписи.

Где и как запускать

Полный модуль собственной управляемой формы толстого Windows-клиента; sync/sync в одной новой VM, runtime0.

Подготовка

  1. Создайте новую отдельную изолированную Windows VM, отдельного только учебного Windows-пользователя и новую пустую файловую ИБ платформы ровно8.5.1.1343. Имя корня конфигурации УчебныеКриптоОповещения85, русский встроенный язык, Такси, совместимость Не использовать. Рабочие пользователи, базы и реальные ключи запрещены.

  2. В этой конфигурации не должно быть предметных объектов, регистров, заданий, внешних источников или подписок; не устанавливайте расширения. Полный server guard каждого модуля проверяет metadata/три источника расширений/версию/транзакцию.

  3. Создайте отдельную внешнюю обработку УчебныеКриптоОповещения85 с основной управляемой формой. Для каждого урока используйте отдельную форму либо целиком заменяйте полный модуль; дублирующие одноименные процедуры не склеивайте.

  4. Реквизиты формы: UUIDКомплекта85 Строка36; ОжидаемыйОтпечаток85 Строка40; КаталогДляКомплекта85 Строка0, ТолькоПросмотр; Статус85 Строка0, многострочный ТолькоПросмотр; ПодтверждаюУчебнуюVM85 Булево исходноЛожь. Назначьте ПриСозданииНаСервере и ПриОткрытии из полного кода. Добавьте команду ВыполнитьКрипто85 с одноименным обработчиком/кнопкой, ИзменяетСохраняемыеДанныеЛожь.

  5. Для трех уроков проверки сертификата дополнительно создайте ПодтверждаюСвоеRootДоверие85 Булево исходноЛожь. Для обычного CMS/BES/callback/audit доверие Root не требуется и этот флаг не используется.

  6. Запускайте обработку только толстым управляемым Windows-клиентом8.5.1.1343 под тем же новым учебным пользователем. Включите режим синхронных вызовов: даже Ждать/callback варианты имеют синхронную подготовку DER/провайдера/собственных хранилищ. Нельзя переносить ключи/менеджер на сервер.

  7. В модуль своей формы вставьте весь основной код выбранного урока. Он проверяет собственный локальный DER и legacy CSP, реальные имена SHA256/RSA/AES256 из возможностей; не выбирает случайный персональный сертификат.

  8. В своей новой VM сохраните полный вспомогательный PowerShell как own_crypto85_fixture.ps1. После открытия формы скопируйте точный клиентский КаталогДляКомплекта85 и вручную в Windows PowerShell5.1 выполните .\own_crypto85_fixture.ps1 -BaseDirectory "скопированный каталог". Только этот ВАШ ручной этап создает один новый selfsigned RSA2048 legacy CSP key/type24/KeyExchange в CurrentUser My и новый публичный DER OwnCrypto85-UUID.

  9. Закрытый ключ NonExportable, KeyProtectionNone — только учебный. Скрипт не устанавливает Root-доверие и не экспортирует private key. Запишите UUID/публичный thumbprint; UUID введите в форму без изменения регистра, а40hexсимволов thumbprint — в ОжидаемыйОтпечаток85. Native Отпечаток имеет тип ДвоичныеДанные/SHA1, поэтому в модуле он переводится в hex перед сравнением с PowerShell. CN субъекта/издателя DER обязательно равен OwnCrypto85-UUID. Не создавайте новые комплекты без проверки результатов прежней подготовки.

  10. Для проверки сертификата сохраните ОТДЕЛЬНЫЙ полный trust-PowerShell как trust_only_own_uuid_der.ps1 и вручную выполните .\trust_only_own_uuid_der.ps1 -BaseDirectory "скопированный каталог" -OwnUUID "точный свой UUID" -ConfirmIsolatedVMTrust, только на этой VM. Он требует0 совпадающих именно СВОИХ Root-cert по UUID subject/thumbprint, не0 всех встроенных Root; сверяет единственный свой My/private key и точный DER; добавляет только свой публичный DER; проверяет1точный own Root и локальную одноэлементную цепочку. Повторный импорт/замена запрещены.

  11. Отключите внешнюю сеть только у своей VM через ее настройки до учебных запусков. Собственный selfsigned не имеет CDP/AIA/TSA адресов, проверки отзыва явно пропускаются; это отдельная ограниченная локальная модель доверия, не production политика безопасности.

  12. После собственного trust-этапа включите дополнительный флаг формы лишь для certificate-check уроков. Математика CMS/BES проверяется отдельно с ПроверятьДополнительныеАтрибутыЛожь; она не является проверкой цепочки. Проверки сертификата сохраняют контроль подписи/времени, не используют AllowTest или IgnoreTime.

  13. Не закрывайте форму/клиент во время ожидания или callback-цепочки. Повторная команда отказывает по Занято85. Успех выставляется только после всех стадий/отрицательных тестов; закрытие процесса не гарантирует выполнение финального callback.

  14. Ручная подготовка оставляет свой сертификат/ключ, а trust-этап еще и свой Root; автоматического удаления/отката нет. Никакие ключи, подписи, хранилища, сети или 1С нами здесь не запускались и не менялись. Все результаты до вашего ручного опыта — ожидаемые, runtime0.

&НаКлиенте
Процедура ВыполнитьКрипто85(Команда)
    Если Занято85 Тогда
        ВызватьИсключение "Свой предыдущий опыт еще не закончен";
    КонецЕсли;
    Занято85 = Истина;
    Статус85 = "Своя attached/detached классификация пока не подтверждена";
    Опыт = Неопределено;
    Попытка
        Опыт = ПодготовитьСвойОпыт85();
        Менеджер = Опыт.Менеджер;
        Менеджер.ВключениеДанныхВПодпись = Ложь;
        Detached = Менеджер.Подписать(Опыт.Данные, Опыт.Сертификат, ТипПодписиКриптографии.CMS);
        Менеджер.ВключениеДанныхВПодпись = Истина;
        Attached = Менеджер.Подписать(Опыт.Данные, Опыт.Сертификат, ТипПодписиКриптографии.CMS);
        Если Менеджер.ПроверитьНаличиеДанныхВПодписи(Detached) Тогда
            ВызватьИсключение "Свой Detached не должен содержать карточку";
        КонецЕсли;
        Если Не Менеджер.ПроверитьНаличиеДанныхВПодписи(Attached) Тогда
            ВызватьИсключение "Свой Attached должен содержать карточку";
        КонецЕсли;
        Подписи = Новый Массив;
        Подписи.Добавить(Detached);
        Подписи.Добавить(Attached);
        Для Каждого Подпись Из Подписи Цикл
            Сертификаты = Менеджер.ПолучитьСертификаты(Подпись);
            Если ТипЗнч(Сертификаты) <> Тип("Массив") Или Сертификаты.Количество() <> 1 Тогда
                ВызватьИсключение "Собственная подпись должна содержать только свой сертификат";
            КонецЕсли;
            ПроверитьСвойСертификат85(Сертификаты[0], Опыт.Сертификат);
        КонецЦикла;
        Возвращенные = Менеджер.ПолучитьДанныеИзПодписи(Attached);
        ПроверитьСвоиБайты85(Возвращенные, Опыт.Данные);
        Хранилище = Менеджер.ПолучитьХранилищеСертификатов(ТипХранилищаСертификатовКриптографии.ПерсональныеСертификаты,
            РасположениеХранилищаСертификатовКриптографии.ДанныеПользователяОС);
        Шифр = Менеджер.Зашифровать(Опыт.Данные, Опыт.Сертификат);
        Получатели = Менеджер.ПолучитьСертификаты(Шифр, Хранилище);
        Если ТипЗнч(Получатели) <> Тип("Массив") Или Получатели.Количество() <> 1 Тогда
            ВызватьИсключение "Реальный CMS-envelope должен разыменовать ровно своего получателя в явно своем My";
        КонецЕсли;
        ПроверитьСвойСертификат85(Получатели[0], Опыт.Сертификат);
        НеCMS = ПолучитьДвоичныеДанныеИзСтроки("not a CMS:" + Опыт.UUID, КодировкаТекста.UTF8);
        ОтказСертификатов = Ложь;
        Попытка
            Менеджер.ПолучитьСертификаты(НеCMS);
        Исключение
            ОтказСертификатов = Истина;
        КонецПопытки;
        ОтказНаличия = Ложь;
        Попытка
            Менеджер.ПроверитьНаличиеДанныхВПодписи(НеCMS);
        Исключение
            ОтказНаличия = Истина;
        КонецПопытки;
        Если Не ОтказСертификатов Или Не ОтказНаличия Тогда
            ВызватьИсключение "Парсеры не должны признавать собственный не-CMS контейнером";
        КонецЕсли;
        Статус85 = "UUID " + Опыт.UUID + ": Detached=Ложь, Attached=Истина; свой DER в обеих подписях; свой получатель AES; Attached вернул исходные байты; не-CMS отвергнут. Математика/доверие этой командой не доказываются";
    Исключение
        Статус85 = "Свой разбор не подтвержден, секреты и подробности криптографии не выводятся";
    КонецПопытки;
    Если Опыт <> Неопределено Тогда
        Опыт.Менеджер.ПарольДоступаКЗакрытомуКлючу = "";
    КонецЕсли;
    Занято85 = Ложь;
КонецПроцедуры

&НаКлиенте
Перем Занято85;

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    ПроверитьСвойПустойСтенд();
    UUIDКомплекта85 = "";
    ОжидаемыйОтпечаток85 = "";
    Статус85 = "Свой криптографический опыт не выполнен";
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
    Занято85 = Ложь;
    КаталогДляКомплекта85 = КаталогВременныхФайлов();
КонецПроцедуры

&НаКлиенте
Функция ПодготовитьСвойОпыт85()
    ПроверитьСеанс85();
    #Если ТолстыйКлиентУправляемоеПриложение Тогда
        Система = Новый СистемнаяИнформация;
        Если (Система.ТипПлатформы <> ТипПлатформы.Windows_x86
            И Система.ТипПлатформы <> ТипПлатформы.Windows_x86_64) Или Не ПодтверждаюУчебнуюVM85 Тогда
            ВызватьИсключение "Нужна собственная изолированная Windows VM и толстый управляемый клиент8.5.1.1343";
        КонецЕсли;
        СвойUUID = Новый УникальныйИдентификатор(UUIDКомплекта85);
        ТекстUUID = НРег(Строка(СвойUUID));
        Если UUIDКомплекта85 <> ТекстUUID Тогда
            ВызватьИсключение "Нужен точный UUID своей PowerShell-подготовки";
        КонецЕсли;
        БазаФайлов = КаталогВременныхФайлов();
        Если Прав(БазаФайлов, 1) <> "\" Тогда
            БазаФайлов = БазаФайлов + "\";
        КонецЕсли;
        ИмяDER = БазаФайлов + "OwnCrypto85-" + ТекстUUID + "\own-public.cer";
        СвойФайл = Новый Файл(ИмяDER);
        Если Не СвойФайл.Существует() Или Не СвойФайл.ЭтоФайл() Тогда
            ВызватьИсключение "Нет своего публичного DER-файла";
        КонецЕсли;
        Если СвойФайл.Размер() <= 0 Или СвойФайл.Размер() > 65536 Тогда
            ВызватьИсключение "Свой DER пуст или слишком велик";
        КонецЕсли;
        Публичный = Новый СертификатКриптографии(Новый ДвоичныеДанные(ИмяDER));
        Субъект = Публичный.Субъект;
        Издатель = Публичный.Издатель;
        Если ТипЗнч(Субъект) <> Тип("ФиксированнаяСтруктура") Или ТипЗнч(Издатель) <> Тип("ФиксированнаяСтруктура") Тогда
            ВызватьИсключение "Native subject/issuer должны быть readonly структурами собственного DER";
        КонецЕсли;
        Если Не Субъект.Свойство("CN", ИмяСубъекта) Или Не Издатель.Свойство("CN", ИмяИздателя) Тогда
            ВызватьИсключение "Нужен реальный CN собственного selfsigned DER";
        КонецЕсли;
        Если ИмяСубъекта <> "OwnCrypto85-" + ТекстUUID Или ИмяИздателя <> ИмяСубъекта Тогда
            ВызватьИсключение "Публичный DER не принадлежит нашему собственному UUID selfsigned комплекту";
        КонецЕсли;
        Если СтрДлина(ОжидаемыйОтпечаток85) <> 40
            Или ВРег(ОжидаемыйОтпечаток85) <> ВРег(ПолучитьHexСтрокуИзДвоичныхДанных(Публичный.Отпечаток)) Тогда
            ВызватьИсключение "Нужен точный публичный SHA1 hex отпечаток из собственной ручной подготовки";
        КонецЕсли;
        Менеджер = Новый МенеджерКриптографии("Microsoft Enhanced RSA and AES Cryptographic Provider", "", 24,
            ИспользованиеИнтерактивногоРежимаКриптографии.НеИспользовать);
        Информация = Менеджер.ПолучитьИнформациюМодуляКриптографии();
        Если ТипЗнч(Информация) <> Тип("ИнформацияМодуляКриптографии") Тогда
            ВызватьИсключение "Свой провайдер не вернул возможности";
        КонецЕсли;
        Если Информация.АлгоритмыХеширования.Найти("SHA256") = Неопределено
            Или Информация.АлгоритмыПодписи.Найти("RSA") = Неопределено
            Или Информация.АлгоритмыШифрования.Найти("AES256") = Неопределено Тогда
            ВызватьИсключение "Нужны подтвержденные названия SHA256/RSA/AES256 этого провайдера. Не подставляйте неизвестные имена";
        КонецЕсли;
        Менеджер.АлгоритмХеширования = "SHA256";
        Менеджер.АлгоритмПодписи = "RSA";
        Менеджер.АлгоритмШифрования = "AES256";
        Менеджер.ВключениеСертификатовВПодпись = РежимВключенияСертификатовКриптографии.ВключатьСертификатСубъекта;
        Менеджер.ПарольДоступаКЗакрытомуКлючу = "";
        Хранилище = Менеджер.ПолучитьХранилищеСертификатов(ТипХранилищаСертификатовКриптографии.ПерсональныеСертификаты,
            РасположениеХранилищаСертификатовКриптографии.ДанныеПользователяОС);
        Кандидат = Хранилище.НайтиПоОтпечатку(Публичный.Отпечаток);
        Если ТипЗнч(Кандидат) <> Тип("СертификатКриптографии") Тогда
            ВызватьИсключение "Нет своего сертификата с привязкой к ключу в Личном текущего пользователя";
        КонецЕсли;
        ПроверитьСвойСертификат85(Кандидат, Публичный);
        ТекстДанных = "OwnCrypto85:" + ТекстUUID + "|Книга|Количество=3|Цена=250";
        Данные = ПолучитьДвоичныеДанныеИзСтроки(ТекстДанных, КодировкаТекста.UTF8);
        Возврат Новый Структура("Менеджер,Сертификат,Данные,UUID", Менеджер, Кандидат, Данные, ТекстUUID);
    #Иначе
        ВызватьИсключение "Полный урок поддерживает только толстый управляемый клиент Windows, не сервер, тонкий, веб или мобильный";
    #КонецЕсли
КонецФункции

&НаКлиенте
Процедура ПроверитьСвойСертификат85(Кандидат, Ожидание)
    Если ТипЗнч(Кандидат) <> Тип("СертификатКриптографии") Тогда
        ВызватьИсключение "Нет реального сертификата в результате";
    КонецЕсли;
    Если Base64Строка(Кандидат.Выгрузить()) <> Base64Строка(Ожидание.Выгрузить()) Тогда
        ВызватьИсключение "Отпечаток без точного DER-совпадения не принимается";
    КонецЕсли;
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ПроверитьСеанс85()
    ПроверитьСвойПустойСтенд();
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ПроверитьСвойПустойСтенд()
    Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
    КонецЕсли;
    Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
        ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
    КонецЕсли;
    Источники = Новый Массив;
    Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
    Для Каждого Источник Из Источники Цикл
        Расширения = РасширенияКонфигурации.Получить(, Источник);
        Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
            ВызватьИсключение "Native список расширений должен иметь тип Массив";
        КонецЕсли;
        Если Расширения.Количество() <> 0 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьСвоиБайты85(Факт, Ожидание)
    Если ТипЗнч(Факт) <> Тип("ДвоичныеДанные") Или Base64Строка(Факт) <> Base64Строка(Ожидание) Тогда
        ВызватьИсключение "Полученные байты не совпали с собственной карточкой";
    КонецЕсли;
КонецПроцедуры

PowerShell: own_crypto85_fixture.ps1

Новая собственная Windows VM, не модуль1С.

Отдельный полный ручной файл только на новой собственной Windows VM: новый собственный CSP-key/My-cert/publicDER; здесь не запускался.

param([Parameter(Mandatory=$true)][string]$BaseDirectory)
$ErrorActionPreference = 'Stop'
if ([Environment]::OSVersion.Platform -ne [PlatformID]::Win32NT) {throw 'Use only your isolated Windows VM'}
$taskBase = (Resolve-Path -LiteralPath $BaseDirectory).Path
if (-not (Test-Path -LiteralPath $taskBase -PathType Container)) {throw 'Copy the real client temporary directory from your own1C form'}
$taskIdentity = [guid]::NewGuid().ToString()
$taskFolder = Join-Path $taskBase ('OwnCrypto85-' + $taskIdentity)
if (Test-Path -LiteralPath $taskFolder) {throw 'Own UUID directory already exists'}
$taskSubject = 'CN=OwnCrypto85-' + $taskIdentity
$taskParameters = @{
    Type = 'Custom'
    Subject = $taskSubject
    FriendlyName = 'OwnCrypto85-' + $taskIdentity
    Provider = 'Microsoft Enhanced RSA and AES Cryptographic Provider'
    Container = 'OwnCrypto85-' + $taskIdentity
    KeyAlgorithm = 'RSA'
    KeyLength = 2048
    KeySpec = 'KeyExchange'
    KeyUsage = @('DigitalSignature','KeyEncipherment')
    KeyExportPolicy = 'NonExportable'
    KeyProtection = 'None'
    HashAlgorithm = 'SHA256'
    NotAfter = (Get-Date).AddDays(7)
    CertStoreLocation = 'Cert:\CurrentUser\My'
}
$taskCertificate = New-SelfSignedCertificate @taskParameters
if ($taskCertificate.Subject -ne $taskSubject -or -not $taskCertificate.HasPrivateKey) {throw 'Own certificate identity/private key not confirmed; inspect your VM manually'}
$taskKey = $taskCertificate.PrivateKey
if ($taskKey -isnot [System.Security.Cryptography.RSACryptoServiceProvider]) {throw 'Expected own legacy RSA CSP key, not CNG'}
try {
    $taskKeyInfo = $taskKey.CspKeyContainerInfo
    if ($taskKeyInfo.ProviderName -ne $taskParameters.Provider -or $taskKeyInfo.ProviderType -ne 24 -or $taskKeyInfo.MachineKeyStore) {throw 'Wrong provider, type or account store'}
    if ($taskKeyInfo.KeyContainerName -ne $taskParameters.Container) {throw 'Wrong own key container'}
    New-Item -ItemType Directory -Path $taskFolder | Out-Null
    $taskDer = $taskCertificate.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Cert)
    $taskFile = Join-Path $taskFolder 'own-public.cer'
    $taskStream = [System.IO.File]::Open($taskFile,[System.IO.FileMode]::CreateNew,[System.IO.FileAccess]::Write,[System.IO.FileShare]::None)
    try { $taskStream.Write($taskDer,0,$taskDer.Length) } finally { $taskStream.Dispose() }
    Write-Output ('Own UUID: ' + $taskIdentity)
    Write-Output ('Own public DER: ' + $taskFile)
    Write-Output ('Own subject: ' + $taskCertificate.Subject)
    Write-Output ('Own thumbprint: ' + $taskCertificate.Thumbprint)
    Write-Output 'A new private key remains in CurrentUser My. No root trust, network, export of private key or automatic cleanup.'
} finally {
    $taskKey.Dispose()
    $taskCertificate.Dispose()
}

Разбор по шагам

  1. Подтвердите свой пустой стенд/VM, точный DER и тот же личный ключ, не произвольный CMS из Интернета.

  2. Создайте два действительных собственных CMS с явным CMS типом и тем же payload: ВключениеДанныхВПодписьЛожь для Detached, Истина для Attached.

  3. ПроверитьНаличиеДанныхВПодписи должен дать Ложь у собственного Detached и Истина у Attached. Флаг из менеджера не выдается за результат метода.

  4. ПолучитьСертификаты вызывается для каждого настоящего signed-container; проверяем массив ровно1сертификата и побайтное равенство своему DER.

  5. ПолучитьДанныеИзПодписи читает Attached; сравниваем UTF8-payload побайтно с собственной карточкой, а не просто выводим parsed-объект.

  6. Создаем AES-envelope для единственного своего сертификата. ПолучитьСертификаты получает envelope и явное собственное My-хранилище для поиска сертификата получателя; это полезный второй вариант новых API, не только замена legacy.

  7. Строка not a CMS с UUID преобразуется в реальные ДвоичныеДанные. Обе операции парсинга должны отвергнуть не-CMS; отсутствие исключения считается провалом.

  8. Сбросьте пароль собственного менеджера и Занято85 после результата/ошибки. Итог не утверждает математическую проверку, доверие, отзыв или доверенное время — они не выполнялись этим разбором.

Как проверить результат

  1. Реальные Detached/Attached дают Ложь/Истина; Attached payload совпадает побайтно.

  2. Обе подписи содержат точный own DER; own recipient envelope разрешен через переданное own My.

  3. Оба не-CMS парсинга отказаны; сертификат из случайного хранилища не принимается.

  4. В режимеЖдать результаты соответствуют native Обещаниям: Bool присутствия/массив сертификатов, не callback и не сертификат сам по себе.

Ожидаемый результат

Ожидаемые ручные значения: DetachedЛожь/AttachedИстина, own DER в обеих подписях и own recipient AES, исходный Attached payload, два отказа не-CMS. Это разбор, не доверие/проверка подписи.

На что обратить внимание

  1. Сертификатов может не быть в иных чужих CMS. В нашей самостоятельной подписи inclusion явно задан; для envelope указан реальный собственный My, а не неизвестный fallback.

  2. Наличие payload не означает его подлинность; ПолучитьСертификаты не импортирует сертификаты и не проверяет доверие.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.