Асинхронная функция. Проверяет сертификат. В случае ошибки генерируется исключительная ситуация.
Синтаксис
ПроверитьСертификатАсинх(<Сертификат>, <РежимПроверки>, <УниверсальнаяДатаПроверки>)Полное описание, параметры и ограничения
МенеджерКриптографии.ПроверитьСертификатАсинх (CryptoManager.CheckCertificateAsync)
МенеджерКриптографии (CryptoManager)
ПроверитьСертификатАсинх (CheckCertificateAsync)
Доступен, начиная с версии 8.3.18.
Синтаксис:
ПроверитьСертификатАсинх(<Сертификат>, <РежимПроверки>, <УниверсальнаяДатаПроверки>)
Параметры:
<Сертификат> (обязательный)
Тип: СертификатКриптографии.
Проверяемый сертификат.
<РежимПроверки> (необязательный)
Тип: РежимПроверкиСертификатаКриптографии, Массив.
Указывает режим проверки.
Содержит один объект или массив объектов режимов проверки.
<УниверсальнаяДатаПроверки> (необязательный)
Тип: Дата.
Время проверки и построения цепочки сертификатов, указывается в универсальном времени (UTC).
Возвращаемое значение:
Тип: Обещание.
В случае успешного результата проверки результатом выполнения обещания является Неопределено. В случае ошибки объект Обещание будет содержать исключение, которое будет выброшено из оператора Ждать, аргументом которого будет данное Обещание.
Описание:
Асинхронная функция. Проверяет сертификат. В случае ошибки генерируется исключительная ситуация.
Доступность:
Тонкий клиент, веб-клиент, мобильный клиент, сервер, толстый клиент, внешнее соединение, мобильное приложение (клиент), мобильное приложение (сервер), мобильный автономный сервер.
См. также:
МенеджерКриптографии, метод ПроверитьСертификат
МенеджерКриптографии, метод НачатьПроверкуСертификата
Использование в версии:
Доступен, начиная с версии 8.3.18.
Описание изменено в версии 8.3.27.
Методическая информация
Практические примеры
Ждать: проверить свой локально доверенный сертификат и UTC-срок
Отдельный явный ручной trust-fixture устанавливает в Root новой VM только свой точный публичный DER. Полный1С модуль проверяет own My/Root, корректность при UTC-дате внутри срока и обязательный отказ после реального срока. Не использует AllowTest/IgnoreTime и не обещает отзыв или qualifiedCA.
Где и как запускать
Полный клиентский модуль собственной формы на новой Windows VM; только отдельный собственный manual Root trust, runtime0.
Подготовка
Создайте новую отдельную изолированную Windows VM, отдельного только учебного Windows-пользователя и новую пустую файловую ИБ платформы ровно8.5.1.1343. Имя корня конфигурации УчебныеКриптоОповещения85, русский встроенный язык, Такси, совместимость Не использовать. Рабочие пользователи, базы и реальные ключи запрещены.
В этой конфигурации не должно быть предметных объектов, регистров, заданий, внешних источников или подписок; не устанавливайте расширения. Полный server guard каждого модуля проверяет metadata/три источника расширений/версию/транзакцию.
Создайте отдельную внешнюю обработку УчебныеКриптоОповещения85 с основной управляемой формой. Для каждого урока используйте отдельную форму либо целиком заменяйте полный модуль; дублирующие одноименные процедуры не склеивайте.
Реквизиты формы: UUIDКомплекта85 Строка36; ОжидаемыйОтпечаток85 Строка40; КаталогДляКомплекта85 Строка0, ТолькоПросмотр; Статус85 Строка0, многострочный ТолькоПросмотр; ПодтверждаюУчебнуюVM85 Булево исходноЛожь. Назначьте ПриСозданииНаСервере и ПриОткрытии из полного кода. Добавьте команду ВыполнитьКрипто85 с одноименным обработчиком/кнопкой, ИзменяетСохраняемыеДанныеЛожь.
Для трех уроков проверки сертификата дополнительно создайте ПодтверждаюСвоеRootДоверие85 Булево исходноЛожь. Для обычного CMS/BES/callback/audit доверие Root не требуется и этот флаг не используется.
Запускайте обработку только толстым управляемым Windows-клиентом8.5.1.1343 под тем же новым учебным пользователем. Включите режим синхронных вызовов: даже Ждать/callback варианты имеют синхронную подготовку DER/провайдера/собственных хранилищ. Нельзя переносить ключи/менеджер на сервер.
В модуль своей формы вставьте весь основной код выбранного урока. Он проверяет собственный локальный DER и legacy CSP, реальные имена SHA256/RSA/AES256 из возможностей; не выбирает случайный персональный сертификат.
В своей новой 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.
Закрытый ключ NonExportable, KeyProtectionNone — только учебный. Скрипт не устанавливает Root-доверие и не экспортирует private key. Запишите UUID/публичный thumbprint; UUID введите в форму без изменения регистра, а40hexсимволов thumbprint — в ОжидаемыйОтпечаток85. Native Отпечаток имеет тип ДвоичныеДанные/SHA1, поэтому в модуле он переводится в hex перед сравнением с PowerShell. CN субъекта/издателя DER обязательно равен OwnCrypto85-UUID. Не создавайте новые комплекты без проверки результатов прежней подготовки.
Для проверки сертификата сохраните ОТДЕЛЬНЫЙ полный 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 и локальную одноэлементную цепочку. Повторный импорт/замена запрещены.
Отключите внешнюю сеть только у своей VM через ее настройки до учебных запусков. Собственный selfsigned не имеет CDP/AIA/TSA адресов, проверки отзыва явно пропускаются; это отдельная ограниченная локальная модель доверия, не production политика безопасности.
После собственного trust-этапа включите дополнительный флаг формы лишь для certificate-check уроков. Математика CMS/BES проверяется отдельно с ПроверятьДополнительныеАтрибутыЛожь; она не является проверкой цепочки. Проверки сертификата сохраняют контроль подписи/времени, не используют AllowTest или IgnoreTime.
Не закрывайте форму/клиент во время ожидания или callback-цепочки. Повторная команда отказывает по Занято85. Успех выставляется только после всех стадий/отрицательных тестов; закрытие процесса не гарантирует выполнение финального callback.
Ручная подготовка оставляет свой сертификат/ключ, а trust-этап еще и свой Root; автоматического удаления/отката нет. Никакие ключи, подписи, хранилища, сети или 1С нами здесь не запускались и не менялись. Все результаты до вашего ручного опыта — ожидаемые, runtime0.
&НаКлиенте
Асинх Процедура ВыполнитьКрипто85(Команда)
Если Занято85 Тогда
ВызватьИсключение "Дождитесь собственной предыдущей проверки";
КонецЕсли;
Занято85 = Истина;
Статус85 = "Свое локальное доверие/срок еще не подтверждены";
Опыт = Неопределено;
Попытка
Опыт = ПодготовитьСвойОпыт85();
ПроверитьСвоеКорневоеДоверие85(Опыт);
Режим = РежимПроверкиСертификатаКриптографии.ИгнорироватьПроверкуВСпискеОтозванныхСертификатов;
ДатаВнутри = Опыт.Сертификат.ДатаНачала + 86400;
ПослеОкончания = Опыт.Сертификат.ДатаОкончания + 86400;
Если ДатаВнутри >= Опыт.Сертификат.ДатаОкончания Тогда
ВызватьИсключение "Свой сертификат должен иметь семь дней учебного срока, UTC-границы берутся из реального DER";
КонецЕсли;
Итог = Ждать Опыт.Менеджер.ПроверитьСертификатАсинх(Опыт.Сертификат, Режим, ДатаВнутри);
Если Итог <> Неопределено Тогда
ВызватьИсключение "Успешное обещание проверки сертификата должно дать Неопределено, не Булево";
КонецЕсли;
ОтказСрока = Ложь;
Попытка
Ждать Опыт.Менеджер.ПроверитьСертификатАсинх(Опыт.Сертификат, Режим, ПослеОкончания);
Исключение
ОтказСрока = Истина;
КонецПопытки;
Если Не ОтказСрока Тогда
ВызватьИсключение "Реальный срок собственного сертификата нельзя игнорировать";
КонецЕсли;
Статус85 = "UUID " + Опыт.UUID + ": точный own DER в My/Root; локальная цепочка при UTC-дате внутри срока принята; дата после срока отказана. Отзыв/OCSP/TSA/юридическая квалификация не проверены";
Исключение
Статус85 = "Собственное Root-доверие/срок не подтверждены. Не включайте AllowTest и не отключайте проверку времени ради успеха";
КонецПопытки;
Если Опыт <> Неопределено Тогда
Опыт.Менеджер.ПарольДоступаКЗакрытомуКлючу = "";
КонецЕсли;
Занято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(Опыт)
Корни = Опыт.Менеджер.ПолучитьХранилищеСертификатов(ТипХранилищаСертификатовКриптографии.КорневыеСертификаты,
РасположениеХранилищаСертификатовКриптографии.ДанныеПользователяОС);
Корневой = Корни.НайтиПоОтпечатку(Опыт.Сертификат.Отпечаток);
Если ТипЗнч(Корневой) <> Тип("СертификатКриптографии") Тогда
ВызватьИсключение "Сначала вручную импортируйте только свой точный DER в Root своей новой VM отдельной стадией";
КонецЕсли;
ПроверитьСвойСертификат85(Корневой, Опыт.Сертификат);
Если Не ПодтверждаюСвоеRootДоверие85 Тогда
ВызватьИсключение "Нужно отдельное явное подтверждение учебного доверия своему DER, не всей ОС";
КонецЕсли;
КонецПроцедуры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()
}
PowerShell: trust_only_own_uuid_der.ps1
Только новая собственная Windows VM, никогда рабочий пользователь/компьютер.
Отдельная явно подтверждаемая ручная стадия: own DER/UUID/My/private-key;0ownRoot→1exactRoot; без смены чужих Root. Здесь trust/stores не менялись.
param(
[Parameter(Mandatory=$true)][string]$BaseDirectory,
[Parameter(Mandatory=$true)][string]$OwnUUID,
[Parameter(Mandatory=$true)][switch]$ConfirmIsolatedVMTrust
)
$ErrorActionPreference = 'Stop'
if (-not $ConfirmIsolatedVMTrust -or [Environment]::OSVersion.Platform -ne [PlatformID]::Win32NT) {throw 'Only an explicitly confirmed own isolated Windows VM'}
$taskUUID = ([guid]::Parse($OwnUUID)).ToString()
if ($taskUUID -ne $OwnUUID -or $taskUUID -eq [guid]::Empty.ToString()) {throw 'Exact nonzero own UUID required'}
$taskBase = (Resolve-Path -LiteralPath $BaseDirectory).Path
$taskFolder = Join-Path $taskBase ('OwnCrypto85-' + $taskUUID)
$taskPublicFile = Join-Path $taskFolder 'own-public.cer'
$taskResolvedFolder = (Resolve-Path -LiteralPath $taskFolder).Path
if ($taskResolvedFolder -ne [System.IO.Path]::GetFullPath($taskFolder)) {throw 'Own UUID path was redirected'}
if ((Get-Item -LiteralPath $taskResolvedFolder).Attributes -band [System.IO.FileAttributes]::ReparsePoint) {throw 'No reparse-point own directory'}
$taskFileInfo = Get-Item -LiteralPath $taskPublicFile
if ($taskFileInfo.PSIsContainer -or $taskFileInfo.Length -le 0 -or $taskFileInfo.Length -gt 65536 -or ($taskFileInfo.Attributes -band [System.IO.FileAttributes]::ReparsePoint)) {throw 'Only own bounded public DER file'}
$taskPublic = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList $taskPublicFile
$taskExpectedSubject = 'CN=OwnCrypto85-' + $taskUUID
$taskOwnDer = [Convert]::ToBase64String($taskPublic.RawData)
$taskMy = New-Object System.Security.Cryptography.X509Certificates.X509Store -ArgumentList 'My','CurrentUser'
$taskRoot = New-Object System.Security.Cryptography.X509Certificates.X509Store -ArgumentList 'Root','CurrentUser'
try {
if ($taskPublic.Subject -ne $taskExpectedSubject -or $taskPublic.Issuer -ne $taskExpectedSubject) {throw 'Only exact own self-signed UUID certificate'}
if ([DateTime]::UtcNow -lt $taskPublic.NotBefore.ToUniversalTime() -or [DateTime]::UtcNow -ge $taskPublic.NotAfter.ToUniversalTime()) {throw 'Own certificate is not currently valid'}
$taskMy.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly)
$taskOwnMy = @($taskMy.Certificates | Where-Object {$_.Thumbprint -eq $taskPublic.Thumbprint -or $_.Subject -eq $taskExpectedSubject})
if ($taskOwnMy.Count -ne 1 -or -not $taskOwnMy[0].HasPrivateKey -or [Convert]::ToBase64String($taskOwnMy[0].RawData) -ne $taskOwnDer) {throw 'Exact sole own My certificate/private-key binding not proven'}
$taskRoot.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
$taskOwnRootBefore = @($taskRoot.Certificates | Where-Object {$_.Thumbprint -eq $taskPublic.Thumbprint -or $_.Subject -eq $taskExpectedSubject})
if ($taskOwnRootBefore.Count -ne 0) {throw 'Own UUID root already exists; do not automatically repeat or replace trust'}
$taskRoot.Add($taskPublic)
$taskOwnRootAfter = @($taskRoot.Certificates | Where-Object {$_.Thumbprint -eq $taskPublic.Thumbprint -or $_.Subject -eq $taskExpectedSubject})
if ($taskOwnRootAfter.Count -ne 1 -or [Convert]::ToBase64String($taskOwnRootAfter[0].RawData) -ne $taskOwnDer) {throw 'Own root DER postcondition not proven; inspect only own VM manually'}
$taskChain = New-Object System.Security.Cryptography.X509Certificates.X509Chain
try {
$taskChain.ChainPolicy.RevocationMode = [System.Security.Cryptography.X509Certificates.X509RevocationMode]::NoCheck
$taskChain.ChainPolicy.VerificationFlags = [System.Security.Cryptography.X509Certificates.X509VerificationFlags]::NoFlag
$taskChain.ChainPolicy.UrlRetrievalTimeout = [TimeSpan]::Zero
if (-not $taskChain.Build($taskPublic)) {throw 'Only local own trust chain failed; no success promised'}
if ($taskChain.ChainElements.Count -ne 1 -or [Convert]::ToBase64String($taskChain.ChainElements[0].Certificate.RawData) -ne $taskOwnDer) {throw 'Expected only our one self-signed local chain element'}
} finally {$taskChain.Dispose()}
Write-Output ('Own UUID root trust added: ' + $taskUUID)
Write-Output ('Own public thumbprint: ' + $taskPublic.Thumbprint)
Write-Output 'Only own DER imported to CurrentUser Root. No revocation/TSA/OCSP/qualified-signature claim; no automatic cleanup.'
} finally {
$taskRoot.Close()
$taskRoot.Dispose()
$taskMy.Close()
$taskMy.Dispose()
$taskPublic.Dispose()
}
Разбор по шагам
Сначала выполните свою CSP/DER-подготовку в новой VM; не ставьте Root-доверие для уроков математики CMS/BES без отдельной необходимости.
Для этой задачи отдельно вручную запустите полный trust-script с точным BaseDirectory, своимUUID и ConfirmIsolatedVMTrust. До Add он доказывает0 совпадающих own Root, после1точный DER; чужие встроенные Root не удаляются/не заменяются.
Подтвердите отдельный Root-флаг формы. 1С получает Root текущего пользователя и ищет именно отпечаток собственного сертификата, затем сравнивает DER побайтно с найденным собственным My.
Даты ДатаНачала/ДатаОкончания в native СертификатКриптографии читаются в UTC. Для положительного пути выбираем реальную ДатаНачала+1день, проверяя ее нахождение до окончания7-дневного сертификата.
ПроверитьСертификатАсинх черезЖдать проверяет actual own cert и дату внутри срока. Пропускается только CRL, поскольку offline-модель не содержит сервера отзыва; подпись и срок не отключаются.
Успешное обещание возвращает Неопределено; проверьте это. Булево/сертификат не являются результатом этого native API.
Отрицательная дата = реальная ДатаОкончания+1день в UTC. Второй вызов должен отказать по сроку; если его нет, итог запрещен.
Итог различает local Root-доверие и срок от математической подписи файла. Ни CRL/OCSP, ни внешняя цепочкаУЦ, ни TSA, ни юридический статус не проверены; не меняйте эти границы сообщением об успехе.
Как проверить результат
My и Root указывают на точный own DER/UUID; неизвестный Root или один похожий thumbprint без DER не принимается.
Положительный UTC-интервал принимается, дата после срока обязательно отвергается.
AllowTest/IgnoreTime/IgnoreSignature отсутствуют; единственное послабление CRL явно объявлено ограничением.
До ручного запуска хранилища и доверие не менялись. Три вида проверки (математика, локальная цепочка, срок) не смешиваются.
Ожидаемый результат
Ожидаемый ручной результат: точный собственный Root принят для локальной одноэлементной цепочки, UTC-дата внутри срока принята, после срока отвергнута. Отзыв/TSA/OCSP/юридическая квалификация не подтверждены.
На что обратить внимание
Импорт публичного DER в Root действительно меняет доверие только после вашего отдельного ручного запуска. На рабочем компьютере такую подготовку использовать запрещено.
РазрешитьТестовыеСертификаты не является доказательством доверия. Урок не использует этот режим и не отключает реальный срок ради успеха.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.