Начинает расшифровку зашифрованных данных. Чтобы метод успешно расшифровал данные, необходимо чтобы: В хранилище персональных сертификатов установлен сертификат, связанный с контейнером открытого ключа; Сертификат указан в качестве одного из получателей зашифрованных данных (перечислен в параметре <СписокПолучателей> метода Зашифровать). Размер исходных зашифрованных данных ограничен 2 Гб (2147483647 байт).
Синтаксис
НачатьРасшифровку(<ОписаниеОповещения>, <ИсходныеДанные>, <Сертификат>, <ПарольДоступаКЗакрытомуКлючу>)НачатьРасшифровку(<ОписаниеОповещения>, <ИсходныеДанные>, <Сертификат>, <ПарольДоступаКЗакрытомуКлючу>)Полное описание, параметры и ограничения
МенеджерКриптографии.НачатьРасшифровку (CryptoManager.BeginDecrypting)
МенеджерКриптографии (CryptoManager)
НачатьРасшифровку (BeginDecrypting)
Доступен, начиная с версии 8.3.6.
Вариант синтаксиса: Данные в двоичном виде
Синтаксис:
НачатьРасшифровку(<ОписаниеОповещения>, <ИсходныеДанные>, <Сертификат>, <ПарольДоступаКЗакрытомуКлючу>)
Параметры:
<ОписаниеОповещения> (обязательный)
Тип: ОписаниеОповещения.
Содержит описание процедуры, которая будет вызвана после завершения расшифровки со следующими параметрами:
<РасшифрованныеДанные> - расшифрованные данные типа ДвоичныеДанные.
<ДополнительныеПараметры> - значение, которое было указано при создании объекта ОписаниеОповещения.
<ИсходныеДанные> (обязательный)
Тип: Строка, ДвоичныеДанные, Поток, ПотокВПамяти, ФайловыйПоток.
Зашифрованные данные.
Данные могут размещаться в файле (в этом случае указывается имя файла) или представлены как ДвоичныеДанные, Поток, ПотокВПамяти или ФайловыйПоток.
<Сертификат> (необязательный)
Тип: СертификатКриптографии.
Сертификат получателя зашифрованных данных, для которого выполняется расшифровка данных.
<ПарольДоступаКЗакрытомуКлючу> (необязательный)
Тип: Строка.
Пароль для доступа к ключевому контейнеру получателя зашифрованных данных.
Описание варианта метода:
Передает расшифрованные данные в параметре типа ДвоичныеДанные.
Вариант синтаксиса: Сохранение данных в файл
Синтаксис:
НачатьРасшифровку(<ОписаниеОповещения>, <ИсходныеДанные>, <Сертификат>, <ПарольДоступаКЗакрытомуКлючу>)
Параметры:
<ОписаниеОповещения> (обязательный)
Тип: ОписаниеОповещения.
Содержит описание процедуры, которая будет вызвана после завершения расшифровки данных со следующими параметрами:
<ИмяФайла> - имя выходного файла с расшифрованными данными.
<ДополнительныеПараметры> - значение, которое было указано при создании объекта ОписаниеОповещения.
<ИмяФайла> - имя выходного файла с расшифрованными данными.
<ДополнительныеПараметры> - значение, которое было указано при создании объекта ОписаниеОповещения.
<ИсходныеДанные> (обязательный)
Тип: Строка, ДвоичныеДанные, Поток, ПотокВПамяти, ФайловыйПоток.
Зашифрованные данные.
Данные могут размещаться в файле (в этом случае указывается имя файла) или представлены как ДвоичныеДанные, Поток, ПотокВПамяти или ФайловыйПоток.
<Сертификат> (необязательный)
Тип: СертификатКриптографии.
Сертификат получателя зашифрованных данных, для которого выполняется расшифровка данных.
<ПарольДоступаКЗакрытомуКлючу> (необязательный)
Тип: Строка.
Пароль для доступа к ключевому контейнеру получателя зашифрованных данных.
Описание варианта метода:
Помещает расшифрованные данные в файл.
Описание:
Начинает расшифровку зашифрованных данных.
Чтобы метод успешно расшифровал данные, необходимо чтобы:
В хранилище персональных сертификатов установлен сертификат, связанный с контейнером открытого ключа;
Сертификат указан в качестве одного из получателей зашифрованных данных (перечислен в параметре <СписокПолучателей> метода Зашифровать).
Размер исходных зашифрованных данных ограничен 2 Гб (2147483647 байт).
Доступность:
Тонкий клиент, веб-клиент, мобильный клиент, сервер, толстый клиент, внешнее соединение, мобильное приложение (клиент), мобильное приложение (сервер), мобильный автономный сервер.
Примечание:
В случае ошибки генерируется исключительная ситуация.
См. также:
МенеджерКриптографии, метод Расшифровать
МенеджерКриптографии, метод РасшифроватьАсинх
Использование в версии:
Доступен, начиная с версии 8.3.6.
Описание изменено в версии 8.3.27.
Методическая информация
Практические примеры
Callback-цепочка: свой CMS и CAdES-BES, измененная карточка и AES roundtrip
Полные реальные обработчики шести native Начать-операций с собственным UUID/context, экспортируемыми callback и трехаргументным обработчиком ошибки. Включает положительные CMS/BES и отказ подмене количества3→4, но не обещает доверие или TSA.
Где и как запускать
Полный модуль управляемой формы только толстого Windows-клиента собственной пустой файловой ИБ/новой VM; будущий ручной опыт, 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 = "Начинается свой callback-криптоцикл, успех еще не подтвержден";
Попытка
К = ПодготовитьСвойОпыт85();
К.Вставить("Запуск", Строка(Новый УникальныйИдентификатор));
К.Вставить("Стадия", "CMS");
К.Вставить("Завершено", Ложь);
К.Вставить("CMS", Неопределено);
К.Вставить("BES", Неопределено);
К.Вставить("Шифр", Неопределено);
К.Вставить("Отчет", "UUID " + К.UUID + ": CMS/BES математически проверены; измененные байты отвергнуты; AES для себя вернул исходные байты. Доверие, отзыв и TSA здесь не проверены");
КонтекстКрипто85 = К;
К.Менеджер.ВключениеДанныхВПодпись = Ложь;
К.Менеджер.НачатьПодписывание(СвоеОповещение85("СвояПодписьCMS85", К), К.Данные, К.Сертификат, ТипПодписиКриптографии.CMS);
Исключение
Занято85 = Ложь;
Статус85 = "Своя подготовка/начало не подтверждены, callback-цикл не завершен";
Если КонтекстКрипто85 <> Неопределено Тогда
ЗавершитьСвойОпыт85(КонтекстКрипто85, Ложь);
КонецЕсли;
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура СвояПодписьCMS85(ПодписанныеДанные, К) Экспорт
Попытка
ПроверитьСвоюСтадию85(К, "CMS");
Если ТипЗнч(ПодписанныеДанные) <> Тип("ДвоичныеДанные") Или ПустаяСтрока(Base64Строка(ПодписанныеДанные)) Тогда
ВызватьИсключение "НачатьПодписывание должен передать реальные собственные CMS-байты";
КонецЕсли;
К.CMS = ПодписанныеДанные;
К.Стадия = "КонтейнерCMS";
К.Менеджер.НачатьПолучениеКонтейнераПодписейКриптографии(СвоеОповещение85("СвойКонтейнерCMS85", К), К.CMS);
Исключение
ЗавершитьСвойОпыт85(К, Ложь);
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура СвойКонтейнерCMS85(Контейнер, К) Экспорт
Попытка
ПроверитьСвоюСтадию85(К, "КонтейнерCMS");
ПроверитьСвойКонтейнер85(Контейнер, К.Сертификат, К.Данные, Ложь, ТипПодписиКриптографии.CMS);
К.Стадия = "СертификатыCMS";
К.Менеджер.НачатьПолучениеСертификатовИзПодписи(СвоеОповещение85("СвоиСертификатыCMS85", К), К.CMS);
Исключение
ЗавершитьСвойОпыт85(К, Ложь);
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура СвоиСертификатыCMS85(Сертификаты, К) Экспорт
Попытка
ПроверитьСвоюСтадию85(К, "СертификатыCMS");
Если ТипЗнч(Сертификаты) <> Тип("Массив") Или Сертификаты.Количество() <> 1 Тогда
ВызватьИсключение "В собственном CMS ровно один реальный сертификат";
КонецЕсли;
ПроверитьСвойСертификат85(Сертификаты[0], К.Сертификат);
К.Стадия = "ПроверкаCMS";
К.Менеджер.НачатьПроверкуПодписи(СвоеОповещение85("СвояПроверкаCMS85", К), К.Данные, К.CMS, Ложь);
Исключение
ЗавершитьСвойОпыт85(К, Ложь);
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура СвояПроверкаCMS85(Сертификат, К) Экспорт
Попытка
ПроверитьСвоюСтадию85(К, "ПроверкаCMS");
ПроверитьСвойСертификат85(Сертификат, К.Сертификат);
Измененные = ПолучитьДвоичныеДанныеИзСтроки("OwnCrypto85:" + К.UUID + "|Книга|Количество=4|Цена=250", КодировкаТекста.UTF8);
Если Base64Строка(Измененные) = Base64Строка(К.Данные) Тогда
ВызватьИсключение "Собственные отрицательные данные должны реально отличаться";
КонецЕсли;
К.Стадия = "ОтказИзмененным";
К.Менеджер.НачатьПроверкуПодписи(СвоеОповещение85("НеверныйУспех85", К), Измененные, К.CMS, Ложь);
Исключение
ЗавершитьСвойОпыт85(К, Ложь);
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура НеверныйУспех85(Сертификат, К) Экспорт
Попытка
ПроверитьСвоюСтадию85(К, "ОтказИзмененным");
ПроверитьСвойСертификат85(Сертификат, К.Сертификат);
Исключение
ЗавершитьСвойОпыт85(К, Ложь);
Возврат;
КонецПопытки;
ЗавершитьСвойОпыт85(К, Ложь);
КонецПроцедуры
&НаКлиенте
Процедура ОшибкаСвоегоОпыта85(ИнформацияОбОшибке, СтандартнаяОбработка, К) Экспорт
СтандартнаяОбработка = Ложь;
Попытка
Если ТипЗнч(ИнформацияОбОшибке) <> Тип("ИнформацияОбОшибке") Тогда
ВызватьИсключение "Native callback ошибки должен передать диагностический объект";
КонецЕсли;
Если К.Стадия <> "ОтказИзмененным" Тогда
ЗавершитьСвойОпыт85(К, Ложь);
Возврат;
КонецЕсли;
ПроверитьСвоюСтадию85(К, "ОтказИзмененным");
К.Стадия = "Шифрование";
К.Менеджер.НачатьШифрование(СвоеОповещение85("СвоеШифрование85", К), К.Данные, К.Сертификат);
Исключение
ЗавершитьСвойОпыт85(К, Ложь);
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура СвоеШифрование85(ЗашифрованныеДанные, К) Экспорт
Попытка
ПроверитьСвоюСтадию85(К, "Шифрование");
Если ТипЗнч(ЗашифрованныеДанные) <> Тип("ДвоичныеДанные")
Или ПустаяСтрока(Base64Строка(ЗашифрованныеДанные))
Или Base64Строка(ЗашифрованныеДанные) = Base64Строка(К.Данные) Тогда
ВызватьИсключение "Шифрование должно дать собственный непустой CMS-envelope, не plaintext";
КонецЕсли;
К.Шифр = ЗашифрованныеДанные;
К.Стадия = "Расшифровка";
К.Менеджер.НачатьРасшифровку(СвоеОповещение85("СвояРасшифровка85", К), К.Шифр, К.Сертификат, "");
Исключение
ЗавершитьСвойОпыт85(К, Ложь);
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура СвояРасшифровка85(РасшифрованныеДанные, К) Экспорт
Попытка
ПроверитьСвоюСтадию85(К, "Расшифровка");
ПроверитьСвоиБайты85(РасшифрованныеДанные, К.Данные);
К.Стадия = "BES";
К.Менеджер.НачатьПодписывание(СвоеОповещение85("СвояПодписьBES85", К), К.Данные, К.Сертификат, ТипПодписиКриптографии.CAdESBES);
Исключение
ЗавершитьСвойОпыт85(К, Ложь);
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура СвояПодписьBES85(ПодписанныеДанные, К) Экспорт
Попытка
ПроверитьСвоюСтадию85(К, "BES");
Если ТипЗнч(ПодписанныеДанные) <> Тип("ДвоичныеДанные") Или ПустаяСтрока(Base64Строка(ПодписанныеДанные)) Тогда
ВызватьИсключение "BES не должен считаться CMS без настоящих данных и разбора";
КонецЕсли;
К.BES = ПодписанныеДанные;
К.Стадия = "КонтейнерBES";
К.Менеджер.НачатьПолучениеКонтейнераПодписейКриптографии(СвоеОповещение85("СвойКонтейнерBES85", К), К.BES);
Исключение
ЗавершитьСвойОпыт85(К, Ложь);
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура СвойКонтейнерBES85(Контейнер, К) Экспорт
Попытка
ПроверитьСвоюСтадию85(К, "КонтейнерBES");
ПроверитьСвойКонтейнер85(Контейнер, К.Сертификат, К.Данные, Ложь, ТипПодписиКриптографии.CAdESBES);
К.Стадия = "ПроверкаBES";
К.Менеджер.НачатьПроверкуПодписи(СвоеОповещение85("СвояПроверкаBES85", К), К.Данные, К.BES, Ложь);
Исключение
ЗавершитьСвойОпыт85(К, Ложь);
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура СвояПроверкаBES85(Сертификат, К) Экспорт
Попытка
ПроверитьСвоюСтадию85(К, "ПроверкаBES");
ПроверитьСвойСертификат85(Сертификат, К.Сертификат);
ЗавершитьСвойОпыт85(К, Истина);
Исключение
ЗавершитьСвойОпыт85(К, Ложь);
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Перем КонтекстКрипто85;
&НаКлиенте
Функция СвоеОповещение85(Имя, К)
Возврат Новый ОписаниеОповещения(Имя, ЭтотОбъект, К, "ОшибкаСвоегоОпыта85", ЭтотОбъект);
КонецФункции
&НаКлиенте
Процедура ПроверитьСвоюСтадию85(К, Имя)
ПроверитьСеанс85();
Если Не Занято85 Или КонтекстКрипто85 = Неопределено Или ТипЗнч(К) <> Тип("Структура") Тогда
ВызватьИсключение "Нет собственного активного крипто-опыта";
КонецЕсли;
Если К.Запуск <> КонтекстКрипто85.Запуск Или К.UUID <> КонтекстКрипто85.UUID
Или К.Стадия <> Имя Или К.Завершено Тогда
ВызватьИсключение "Подменен UUID/запуск/порядок собственной callback-цепочки";
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ЗавершитьСвойОпыт85(К, Успех)
Если К.Завершено Тогда
Возврат;
КонецЕсли;
К.Завершено = Истина;
К.Менеджер.ПарольДоступаКЗакрытомуКлючу = "";
Занято85 = Ложь;
Если Успех Тогда
Статус85 = К.Отчет;
Иначе
Статус85 = "Собственный криптографический опыт не подтвержден. Проверьте только свою изолированную VM; секреты и диагностический объект не выводятся";
КонецЕсли;
КонтекстКрипто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(Контейнер, Сертификат, Данные, Присоединенная, ОжидаемыйТип)
Если ТипЗнч(Контейнер) <> Тип("КонтейнерПодписейКриптографии") Тогда
ВызватьИсключение "Парсер не вернул контейнер подписей";
КонецЕсли;
Подписи = Контейнер.Подписи;
Если ТипЗнч(Подписи) <> Тип("Массив") Или Подписи.Количество() <> 1 Тогда
ВызватьИсключение "У своего CMS должен быть ровно один подписант";
КонецЕсли;
Подпись = Подписи[0];
Если ТипЗнч(Подпись) <> Тип("ПодписьКриптографии") Или Подпись.Индекс <> 0 Тогда
ВызватьИсключение "Не подтвержден первый собственный подписант";
КонецЕсли;
ПроверитьСвойСертификат85(Подпись.СертификатПодписи, Сертификат);
Если Подпись.ТипПодписи <> ОжидаемыйТип Или ПустаяСтрока(Подпись.АлгоритмПодписи)
Или ПустаяСтрока(Подпись.АлгоритмХеширования) Тогда
ВызватьИсключение "Нет типа CMS или OID алгоритмов в своем контейнере";
КонецЕсли;
Если Присоединенная Тогда
ПроверитьСвоиБайты85(Подпись.Данные, Данные);
ИначеЕсли Подпись.Данные <> Неопределено Тогда
ВызватьИсключение "Отсоединенная подпись неожиданно содержит payload";
КонецЕсли;
АрхивныеМетки = Подпись.АрхивныеМеткиВремени;
Если АрхивныеМетки <> Неопределено Тогда
Если ТипЗнч(АрхивныеМетки) <> Тип("Массив") Или АрхивныеМетки.Количество() <> 0 Тогда
ВызватьИсключение "В своем обычном CMS не ожидаются архивные метки";
КонецЕсли;
КонецЕсли;
Если Подпись.МеткаВремениПодписи <> Неопределено Или Подпись.МеткаВремениДанныхПроверкиПодписи <> Неопределено Тогда
ВызватьИсключение "Обычный CMS не должен подменяться доверенной меткой времени";
КонецЕсли;
Если ТипЗнч(Подпись.НеподтвержденноеВремяПодписи) <> Тип("Дата") Тогда
ВызватьИсключение "Неподтвержденное UTC-время не является датой";
КонецЕсли;
Цепочка = Подпись.СертификатыПроверкиПодписи;
Если ТипЗнч(Цепочка) <> Тип("Массив") Тогда
ВызватьИсключение "Ожидался массив сертификатов из своего CMS";
КонецЕсли;
Для Каждого Участник Из Цепочка Цикл
ПроверитьСвойСертификат85(Участник, Сертификат);
КонецЦикла;
Сообщить("Разобран один собственный CMS. OID: " + Подпись.АлгоритмПодписи + "; " + Подпись.АлгоритмХеширования
+ ". UTC-время неподтвержденное, доверие не проверено");
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьСвоиБайты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()
}
Разбор по шагам
Нажатие запускает новый собственный UUID-сеанс после полного guard. Менеджер/реальный сертификат/UTF8-карточка приходят из самостоятельной DER/CSP-подготовки, а не входного неизвестного объекта.
НачатьПодписывание вызывается с явным собственным сертификатом и ТипПодписиКриптографии.CMS. Callback СвояПодписьCMS85 получает ДвоичныеДанные и К; не Обещание и не имя файла.
НачатьПолучениеКонтейнераПодписейКриптографии передает настоящий контейнер; проверяем единственного своего подписанта, точный DER, detached-пустой payload, отсутствие доверенных/архивных меток.
НачатьПолучениеСертификатовИзПодписи получает именно CMS и возвращает массив с единственным own DER. Метод legacy: с8.3.24 native рекомендует ПолучитьСертификаты/Асинх; современные самостоятельные примеры представлены рядом.
НачатьПроверкуПодписи проверяет исходную карточку, возвращая СертификатКриптографии в callback. ФлагЛожь ограничивает проверку математикой подписи; сертификат/цепочка/отзыв здесь не проверяются.
Отдельная измененная карточка содержит количество4 вместо3 и проверяется той же подписью. Callback успеха НеверныйУспех85 всегда проваливает урок. Лишь native error callback для стадии ОтказИзмененным разрешает продолжение.
ОшибкаСвоегоОпыта85 имеет порядок ИнформацияОбОшибке, СтандартнаяОбработка, К. На чужой стадии ошибка завершает опыт неуспехом; diagnostic/секреты не печатаются. Отключение стандартного показа не скрывает итог неподтвержденного результата.
НачатьШифрование принимает одного своего получателя и возвращает собственный CMS-envelope. НачатьРасшифровку получает этот envelope, тот же сертификат и пустой пароль своего учебного ключа. Полученные байты сравниваются с исходными.
Затем реально подписываем тот же payload типом CAdESBES; разбираем контейнер с проверкой именно CAdESBES и математически проверяем подпись. Это Basic Electronic Signature без TSA, не qualified/архивная подпись.
Каждая стадия проверяет собственный UUID запуска, активный К и точный порядок. Только последняя проверка BES после успешного AES/отказа измененным байтам выставляет общий успех и снимает Занято85.
Как проверить результат
Реальные CMS/BES контейнеры имеют одного собственного подписанта, точный DER и соответствующий тип; CMS не подменяется объявлением BES без разбора.
Измененные байты обязательно отказаны; ошибка любой другой стадии не считается ожидаемой.
AES расшифровка побайтно совпадает с собственным payload; непустые имена/объекты не заменяют эту проверку.
Callback успешных операций имеет2аргумента, ошибки3; итог только после всей цепочки. Root-доверие здесь не нужно, TSA/OCSP/архивные метки отсутствуют.
Ожидаемый результат
Ожидаемый ручной результат: CMS и BES математически проверены, количество4 отвергнуто, AES вернул исходные байты. Доверие/отзыв/доверенное время/юридическая квалификация не подтверждаются.
На что обратить внимание
Выходной сертификат синхронного ПроверитьПодпись не переносится в аргументы НачатьПроверкуПодписи: у callback-схемы сертификат приходит в процедуру завершения.
Формат callback НачатьРасшифровку в installed справке повторяет одинаковую сигнатуру для двух вариантов. Здесь используется только четко документированный двоичный результат, не выдуманный дополнительный выходной параметр.
CAdESBES не требует TSA в этой модели. Остальные CAdES-форматы не объявляются созданными/проверенными без своего реального TSA/OCSP/архивного стенда.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.