ЗащищенноеСоединениеOpenSSL

Типы · OpenSSLSecureConnection

Объект защищенного соединения OpenSSL. Используемый клиентский сертификат должен быть самоподписанным или проходить валидацию через сертификаты удостоверяющих центров, заданные в свойстве СертификатыУдостоверяющихЦентров.

Примеры платформы

ssl1 = Новый ЗащищенноеСоединениеOpenSSL(
            Новый СертификатКлиентаОС,
            Новый СертификатыУдостоверяющихЦентровОС,
            РежимПроверкиОтзываСертификатовУдостоверяющихЦентров.Строгий);
ssl2 = Новый ЗащищенноеСоединениеOpenSSL(
            Новый СертификатКлиентаОС(СпособВыбораСертификатаОС.Авто),
            Новый СертификатыУдостоверяющихЦентровФайл("C:/certs/myca.pem"));
ssl3 = Новый ЗащищенноеСоединениеOpenSSL(
            Новый СертификатКлиентаФайл("C:/certs/user.p12", "password" ),
            Новый СертификатыУдостоверяющихЦентровФайл("C:/certs/myca.pem"));
ssl4 = Новый ЗащищенноеСоединениеOpenSSL(неопределено, неопределено);
Полное описание, параметры и ограничения

ЗащищенноеСоединениеOpenSSL (OpenSSLSecureConnection)

ЗащищенноеСоединениеOpenSSL (OpenSSLSecureConnection)

Доступен, начиная с версии 8.3.1.

Свойства:
РежимПроверкиОтзываTLSСертификатаСервера (ServerTLSCertificateRevocationCheckMode)
СертификатКлиента (ClientCertificate)
СертификатыУдостоверяющихЦентров (CertificationAuthorityCertificates)

Конструкторы:
По объектам используемых сертификатов

Описание:

Объект защищенного соединения OpenSSL.
Используемый клиентский сертификат должен быть самоподписанным или проходить валидацию через сертификаты удостоверяющих центров, заданные в свойстве СертификатыУдостоверяющихЦентров.

Доступность:

Тонкий клиент, веб-клиент, мобильный клиент, сервер, толстый клиент, внешнее соединение, мобильное приложение (клиент), мобильное приложение (сервер), мобильный автономный сервер.

Пример:

ssl1 = Новый ЗащищенноеСоединениеOpenSSL(
Новый СертификатКлиентаОС,
Новый СертификатыУдостоверяющихЦентровОС,
РежимПроверкиОтзываСертификатовУдостоверяющихЦентров.Строгий);

ssl2 = Новый ЗащищенноеСоединениеOpenSSL(
Новый СертификатКлиентаОС(СпособВыбораСертификатаОС.Авто),
Новый СертификатыУдостоверяющихЦентровФайл("C:/certs/myca.pem"));

ssl3 = Новый ЗащищенноеСоединениеOpenSSL(
Новый СертификатКлиентаФайл("C:/certs/user.p12", "password" ),
Новый СертификатыУдостоверяющихЦентровФайл("C:/certs/myca.pem"));

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

См. также:
СертификатКлиентаОС
СертификатКриптографии
СертификатКлиентаФайл
СертификатыУдостоверяющихЦентровОС
СертификатыУдостоверяющихЦентровФайл

Использование в версии:

Доступен, начиная с версии 8.3.1.

Описание изменено в версии 8.3.24.

Методическая информация

Практические примеры

Подготовить HTTPS-соединение с проверкой сертификата

Настраиваем доверенные сертификаты и таймаут. Создание объекта соединения само по себе не отправляет запрос.

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

Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.

Подготовка

  1. Серверный Windows-контекст с доступным хранилищем доверенных сертификатов ОС.

  2. В коде нет вызова Получить или ОтправитьДляОбработки: сеть не используется.

  3. example.com — учебный хост, не адрес Avito.

Сертификаты = Новый СертификатыУдостоверяющихЦентровОС;
TLS = Новый ЗащищенноеСоединениеOpenSSL(, Сертификаты);
Соединение = Новый HTTPСоединение("example.com", 443, , , , 30, TLS);
Сообщить(Соединение.Сервер);
Сообщить(Соединение.Порт);
Сообщить(Соединение.Таймаут);

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

  1. Источник сертификатов ОС передаём вторым параметром OpenSSL.

  2. Без источника удостоверяющих центров OpenSSL не проверяет сертификат сервера.

  3. В HTTPСоединение задаём порт 443, таймаут 30 секунд и TLS-объект.

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

  1. Свойства соединения: example.com, 443, 30.

  2. В отладчике проверьте наличие объекта СертификатыУдостоверяющихЦентров у TLS.

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

Объект соединения подготовлен; запрос не отправлен.

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

  1. Наличие объекта TLS не доказывает успех рукопожатия: это проверяется только при реальном запросе.

  2. Не отключайте проверку сертификата для обхода ошибки доверия.

  3. Для Linux используйте поддерживаемый источник доверенных сертификатов; этот сценарий явно Windows-ориентированный.

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

Подготовить свой CA и клиентский PKCS12 с закрытым ключом, затем собрать файловый TLS-профиль

Полный офлайн-урок начинается с создания собственных сертификатов, а не с неизвестного файла. Проверяет UUID, размеры и SHA256, раздельно загружает CA и клиентский ключ, сверяет readonly-паспорта источников и профиля.

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

Полный модуль основной управляемой формы УчебныеФайловыеTLS85. Собственный толстый управляемый Windows-клиент8.5.1.1343; не серверный модуль. Python отдельно, в своей VM.

Подготовка

  1. Используйте только собственную изолированную WindowsVM и новую пустую базу8.5.1.1343 с именем конфигурации УчебныеФайловыеTLS85, русский встроенный язык, Такси, совместимость Не использовать. Предметные объекты/расширения/задания запрещены guard. Не импортируйте production-сертификаты и не используйте рабочие ключи.

  2. Создайте внешнюю обработку УчебныеФайловыеTLS85, основную управляемую форму. Реквизиты: КаталогДляКомплекта85 Строка длиной0, ТолькоПросмотр; UUIDКомплекта85 Строка длиной36; ПарольКомплекта85 Строка длиной64; Статус85 Строка длиной0, ТолькоПросмотр. У поля пароля включите РежимПароля, не сохраняйте значение настройками/при закрытии. Команда ПроверитьФайловыйПрофиль85, одноименное действие, кнопка, ИзменяетСохраняемыеДанные выключено. Назначьте ПриСозданииНаСервере и ПриОткрытии; основной блок вставьте целиком в модуль этой формы.

  3. Откройте свою обработку толстым управляемым клиентом Windows8.5.1.1343. КаталогДляКомплекта85 показывает фактический клиентский временный каталог1С. Не угадывайте его по TEMP/Python: у приложений пути могут различаться. Скопируйте этот точный путь для аргумента --base следующего скрипта.

  4. На той же собственной VM подготовьте Python3 и отдельное виртуальное окружение: python -m venv .venv; затем .venv\Scripts\python.exe -m pip install cryptography==48.0.0. Эти команды выполняете вы вручную; пакеты в вашем рабочем окружении здесь не устанавливались. Сохраните отдельный нижний блок Python как own_tls85_fixture.py в собственной учебной папке. Не вставляйте Python в модуль1С.

  5. В терминале этой VM запустите .venv\Scripts\python.exe own_tls85_fixture.py --base "точный путь КаталогДляКомплекта85 из вашей формы". Придумайте новый только учебный пароль из16-64 печатных ASCII-символов и повторите его: getpass не выводит ввод. Скрипт сам создает свежий UUID-каталог OwnTLS85-UUID, ca.pem, client.p12 и manifest.json, не перезаписывает существующие файлы. Вводите реальный показанный UUID в UUIDКомплекта85, пароль — в поле пароля формы.

  6. Скрипт — полноценная подготовка источников: CA имеет BasicConstraints ca=True/path_length0 и право подписи; клиент имеет ca=False, CLIENT_AUTH и свой RSA-ключ, подписан собственным CA. PKCS12 содержит закрытый ключ, клиентский сертификат и CA. Скрипт перечитывает собственный PKCS12 и сверяет ключ и отпечатки до записи. В ca.pem только публичный CA, приватный ключ CA вообще не сохраняется. Сертификаты действуют семь суток от фактического UTC-времени запуска.

  7. Держите каталог только в отдельной VM под собственным учебным пользователем; mode0700 не является обещанием WindowsACL. PKCS12-пароль не заменяет защиту каталога и не предназначен для отправки ключа другим людям. Не импортируйте CA в доверие ОС и не устанавливайте личный сертификат. После опыта закройте форму и вручную удалите только напечатанный собственный UUID-каталог или утилизируйте учебную VM. Автоматического удаления/сети в примерах нет.

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

&НаКлиенте
Процедура ПриОткрытии(Отказ)
    КаталогДляКомплекта85 = КаталогВременныхФайлов();
    Если Прав(КаталогДляКомплекта85, 1) <> "\" Тогда
        КаталогДляКомплекта85 = КаталогДляКомплекта85 + "\";
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьФайловыйПрофиль85(Команда)
    ЛокальныйПароль = ПарольКомплекта85;
    ПарольКомплекта85 = "";
    Статус85 = "Проверка не подтверждена";
    Попытка
        ПроверитьСеанс85();
        #Если ТолстыйКлиентУправляемоеПриложение Тогда
            Система = Новый СистемнаяИнформация;
            Если (Система.ТипПлатформы <> ТипПлатформы.Windows_x86 И Система.ТипПлатформы <> ТипПлатформы.Windows_x86_64) Тогда
                ВызватьИсключение "Нужен собственный толстый управляемый Windows-клиент8.5.1.1343";
            КонецЕсли;
            Если СтрДлина(ЛокальныйПароль) < 16 Или СтрДлина(ЛокальныйПароль) > 64 Тогда
                ВызватьИсключение "Введите пароль своего учебного комплекта";
            КонецЕсли;
            СвойUUID = Новый УникальныйИдентификатор(UUIDКомплекта85);
            ТекстUUID = НРег(Строка(СвойUUID));
            Если UUIDКомплекта85 <> ТекстUUID Тогда
                ВызватьИсключение "Нужен точный UUID, выведенный своим Python-скриптом";
            КонецЕсли;
            БазаФайлов = КаталогВременныхФайлов();
            Если Прав(БазаФайлов, 1) <> "\" Тогда
                БазаФайлов = БазаФайлов + "\";
            КонецЕсли;
            СвойКаталог = БазаФайлов + "OwnTLS85-" + ТекстUUID + "\";
            ИмяCA = СвойКаталог + "ca.pem";
            ИмяКлиента = СвойКаталог + "client.p12";
            ИмяМанифеста = СвойКаталог + "manifest.json";
            ПроверитьСвойФайл85(ИмяМанифеста, 16384);
            ПроверитьСвойФайл85(ИмяCA, 65536);
            ПроверитьСвойФайл85(ИмяКлиента, 262144);
            Читатель = Новый ЧтениеJSON;
            Попытка
                Читатель.ОткрытьФайл(ИмяМанифеста);
                Манифест = ПрочитатьJSON(Читатель);
                Читатель.Закрыть();
            Исключение
                Читатель.Закрыть();
                ВызватьИсключение;
            КонецПопытки;
            Если ТипЗнч(Манифест) <> Тип("Структура") Тогда
                ВызватьИсключение "Не получен собственный манифест";
            КонецЕсли;
            Если Не Манифест.Свойство("lesson", Метка) Или Метка <> "OwnTLS85-file-source"
                Или Не Манифест.Свойство("identity", UUIDМанифеста) Или UUIDМанифеста <> ТекстUUID Тогда
                ВызватьИсключение "Манифест другого опыта";
            КонецЕсли;
            Если Не Манифест.Свойство("client_private_key_included", ЕстьКлюч) Или ЕстьКлюч <> Истина
                Или Не Манифест.Свойство("ca_certificate_only", ТолькоСертификатCA) Или ТолькоСертификатCA <> Истина
                Или Не Манифест.Свойство("imported_into_os", Импортирован) Или Импортирован <> Ложь Тогда
                ВызватьИсключение "Паспорт собственного учебного комплекта неверен";
            КонецЕсли;
            Если Не Манифест.Свойство("ca_sha256", ХешCA) Или ТипЗнч(ХешCA) <> Тип("Строка")
                Или Не Манифест.Свойство("client_sha256", ХешКлиента) Или ТипЗнч(ХешКлиента) <> Тип("Строка") Тогда
                ВызватьИсключение "Нет собственных контрольных сумм";
            КонецЕсли;
            Если ПолучитьСвойХеш85(ИмяCA) <> ХешCA Или ПолучитьСвойХеш85(ИмяКлиента) <> ХешКлиента Тогда
                ВызватьИсключение "Файлы изменились после создания манифеста";
            КонецЕсли;
            ЦентрыФайл = Новый СертификатыУдостоверяющихЦентровФайл(ИмяCA);
            КлиентФайл = Новый СертификатКлиентаФайл(ИмяКлиента, ЛокальныйПароль);
            ЛокальныйПароль = "";
            Если ЦентрыФайл.ИмяФайла <> ИмяCA Или КлиентФайл.ИмяФайла <> ИмяКлиента Тогда
                ВызватьИсключение "Источники не сохранили свои имена файлов";
            КонецЕсли;
            Профиль = Новый ЗащищенноеСоединениеOpenSSL(КлиентФайл, ЦентрыФайл);
            Если ТипЗнч(Профиль.СертификатКлиента) <> Тип("СертификатКлиентаФайл")
                Или ТипЗнч(Профиль.СертификатыУдостоверяющихЦентров) <> Тип("СертификатыУдостоверяющихЦентровФайл") Тогда
                ВызватьИсключение "TLS потерял собственные файловые источники";
            КонецЕсли;
            Если Профиль.СертификатКлиента.ИмяФайла <> ИмяКлиента
                Или Профиль.СертификатыУдостоверяющихЦентров.ИмяФайла <> ИмяCA Тогда
                ВызватьИсключение "TLS содержит другие файловые источники";
            КонецЕсли;
            Статус85 = "Собственный файловый TLS-профиль подготовлен. Сеть, доверие серверу, отзыв и mTLS-вход не проверены";
            Сообщить(Статус85);
        #Иначе
            ВызватьИсключение "Для синхронного SHA256 нужен толстый управляемый клиент. Урок не переносится в тонкий/веб-клиент";
        #КонецЕсли
    Исключение
        ЛокальныйПароль = "";
        Сообщить("Проверка не подтверждена. Проверьте свою VM, UUID, файлы, формат PKCS12 и пароль. Пароль и приватный ключ не выводятся");
    КонецПопытки;
    ЛокальныйПароль = "";
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьСвойФайл85(ИмяФайла, МаксимальныйРазмер)
    СвойФайл = Новый Файл(ИмяФайла);
    Если Не СвойФайл.Существует() Или Не СвойФайл.ЭтоФайл() Тогда
        ВызватьИсключение "Нет собственного файла опыта";
    КонецЕсли;
    Размер = СвойФайл.Размер();
    Если Размер <= 0 Или Размер > МаксимальныйРазмер Тогда
        ВызватьИсключение "Свой файл пуст или слишком велик";
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Функция ПолучитьСвойХеш85(ИмяФайла)
    #Если ТолстыйКлиентУправляемоеПриложение Тогда
    Данные = Новый ДвоичныеДанные(ИмяФайла);
    Хеш = Новый ХешированиеДанных(ХешФункция.SHA256);
    Хеш.Добавить(Данные);
    Возврат НРег(ПолучитьHexСтрокуИзДвоичныхДанных(Хеш.ХешСумма));
    #Иначе
    ВызватьИсключение "Синхронный хеш этого урока доступен только в толстом управляемом клиенте";
    #КонецЕсли
КонецФункции

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

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

Отдельный файл own_tls85_fixture.py в своей изолированной WindowsVM; не модуль1С

Python3 и cryptography48.0.0. Ручной запуск создает только новый собственный UUID-каталог, настоящие учебные ключи и сертификаты. Этот блок здесь не исполнялся.

import argparse
import getpass
import hashlib
import importlib.metadata
import json
import os
import sys
import uuid
from datetime import datetime, timedelta, timezone
from pathlib import Path

from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.serialization import pkcs12
from cryptography.x509.oid import ExtendedKeyUsageOID, NameOID


def build_own_fixture(base, password):
    if os.name != "nt" or importlib.metadata.version("cryptography") != "48.0.0":
        raise RuntimeError("Use your isolated Windows VM and cryptography48.0.0")
    base = Path(base).resolve(strict=True)
    if not base.is_dir():
        raise ValueError("Copy the existing temporary directory from your own1C form")
    if not 16 <= len(password) <= 64 or not password.isascii() or not password.isprintable():
        raise ValueError("Use a new training-only printable ASCII password,16-64 characters")
    identity = str(uuid.uuid4())
    now = datetime.now(timezone.utc)
    expiry = now + timedelta(days=7)
    ca_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
    client_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
    ca_name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "OwnTLS85 CA " + identity)])
    client_name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "OwnTLS85 Client " + identity)])
    ca = (x509.CertificateBuilder().subject_name(ca_name).issuer_name(ca_name)
          .public_key(ca_key.public_key()).serial_number(x509.random_serial_number())
          .not_valid_before(now - timedelta(minutes=5)).not_valid_after(expiry)
          .add_extension(x509.BasicConstraints(ca=True, path_length=0), critical=True)
          .add_extension(x509.KeyUsage(digital_signature=True, content_commitment=False, key_encipherment=False,
                                      data_encipherment=False, key_agreement=False, key_cert_sign=True,
                                      crl_sign=True, encipher_only=None, decipher_only=None), critical=True)
          .sign(ca_key, hashes.SHA256()))
    client = (x509.CertificateBuilder().subject_name(client_name).issuer_name(ca_name)
              .public_key(client_key.public_key()).serial_number(x509.random_serial_number())
              .not_valid_before(now - timedelta(minutes=5)).not_valid_after(expiry)
              .add_extension(x509.BasicConstraints(ca=False, path_length=None), critical=True)
              .add_extension(x509.KeyUsage(digital_signature=True, content_commitment=False, key_encipherment=True,
                                          data_encipherment=False, key_agreement=False, key_cert_sign=False,
                                          crl_sign=False, encipher_only=None, decipher_only=None), critical=True)
              .add_extension(x509.ExtendedKeyUsage([ExtendedKeyUsageOID.CLIENT_AUTH]), critical=False)
              .sign(ca_key, hashes.SHA256()))
    client.verify_directly_issued_by(ca)
    ca_bytes = ca.public_bytes(serialization.Encoding.PEM)
    client_bytes = pkcs12.serialize_key_and_certificates(identity.encode("ascii"), client_key, client, [ca],
                                                       serialization.BestAvailableEncryption(password.encode("ascii")))
    loaded_key, loaded_client, loaded_ca = pkcs12.load_key_and_certificates(client_bytes, password.encode("ascii"))
    if loaded_key is None or loaded_client is None or len(loaded_ca) != 1:
        raise RuntimeError("OwnPKCS12 must contain a private key, client certificate and one CA")
    if loaded_key.public_key().public_numbers() != client_key.public_key().public_numbers():
        raise RuntimeError("OwnPKCS12 private key mismatch")
    if loaded_client.fingerprint(hashes.SHA256()) != client.fingerprint(hashes.SHA256()):
        raise RuntimeError("OwnPKCS12 client certificate mismatch")
    if loaded_ca[0].fingerprint(hashes.SHA256()) != ca.fingerprint(hashes.SHA256()):
        raise RuntimeError("OwnPKCS12 CA mismatch")
    folder = base / ("OwnTLS85-" + identity)
    folder.mkdir(mode=0o700, exist_ok=False)
    manifest = dict(lesson="OwnTLS85-file-source", identity=identity,
                    ca_sha256=hashlib.sha256(ca_bytes).hexdigest(), client_sha256=hashlib.sha256(client_bytes).hexdigest(),
                    client_private_key_included=True, ca_certificate_only=True, imported_into_os=False,
                    expires_utc=expiry.isoformat())
    for filename, payload in (("ca.pem", ca_bytes), ("client.p12", client_bytes),
                              ("manifest.json", json.dumps(manifest, ensure_ascii=True, indent=2).encode("utf-8"))):
        with (folder / filename).open("xb") as stream:
            stream.write(payload)
    return identity, folder, expiry


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--base", required=True)
    arguments = parser.parse_args()
    if not sys.stdin.isatty():
        raise RuntimeError("Run interactively in your own VM; do not pipe or log a private password")
    password = getpass.getpass("New training-only PKCS12 password: ")
    confirmation = getpass.getpass("Repeat password: ")
    if password != confirmation:
        raise ValueError("Password confirmation differs")
    identity, folder, expiry = build_own_fixture(arguments.base, password)
    password = confirmation = ""
    print("Own UUID:", identity)
    print("Own folder:", folder)
    print("Expires UTC:", expiry.isoformat())
    print("No OS import or network connection. CA private key was never written to disk.")


if __name__ == "__main__":
    main()

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

  1. Команда сначала копирует пароль в локальную клиентскую переменную и очищает поле. ПроверитьСеанс85 — НаСервереБезКонтекста: пароль и пути не передаются в серверную процедуру. Отдельно проверяются версия толстого клиента и Windows-платформа; этот полный синхронный вариант не обещается для тонкого/веб-клиента, поскольку ХешированиеДанных.Добавить здесь доступен в толстом клиенте.

  2. UUID разбирается настоящим конструктором УникальныйИдентификатор и сверяется с каноническим текстом Python. Произвольный путь, путь с .., URL, другой каталог или другой файл нельзя ввести в команду: все три имени строятся из фактического клиентского временного каталога, собственного UUID и фиксированных имен ca.pem/client.p12/manifest.json.

  3. Проверяем существование, ЭтоФайл и размеры до чтения:16КиБ для манифеста,64КиБ для CA,256КиБ для PKCS12. JSON читается через настоящий ЧтениеJSON, закрывается и при успехе, и при ошибке. Маркер/UUID/flags подтверждают ожидаемый формат собственного опыта, не криптографическое авторство чужого манифеста.

  4. SHA256 считается по реальным ДвоичныеДанные из файла, не по строке имени. Отдельный объект ХешированиеДанных получает алгоритм SHA256 и Добавить(Данные); его ХешСумма преобразуется в hex и нижний регистр. Два результата должны совпасть с собственным манифестом. Проверка обнаруживает случайное изменение файлов, но не защищает от человека, способного изменить и манифест, и файлы.

  5. СертификатыУдостоверяющихЦентровФайл получает полный путь ca.pem без пароля, потому что файл публичный. СертификатКлиентаФайл получает полный путь client.p12 и именно его пароль. Это принципиально разные источники: сертификат без закрытого ключа не заменяет клиентский PKCS12. ИмяФайла у обоих readonly и проверяется чтением, не присваиванием.

  6. ЗащищенноеСоединениеOpenSSL получает реальный КлиентФайл первым аргументом и реальные ЦентрыФайл вторым. Проверяются типы обоих источников и имена файлов уже через readonly-паспорт TLS. CA не пропускается даже для учебного клиента. Нет HTTPСоединение, запроса, адреса сервера или обмена.

  7. Пароль очищается из локальной переменной после создания источника и в общем обработчике исключения. Сообщения не содержат пароля, ключа, полных бинарных данных или ОписаниеОшибки. Очистка строк не гарантирует стирания всех копий из памяти1С/Python, внутреннего объекта и отладчика: после своего опыта завершите учебные процессы. Исключение оставляет неподтвержденный статус, успешный результат не подставляется.

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

  1. Положительный опыт выполняете вручную в своей VM: скрипт выдает свежий UUID и три собственных файла, затем форма с тем же UUID/паролем подтверждает файловые паспорта. В отладчике оба свойства ИмяФайла указывают именно на свой UUID-каталог. Сетевого трафика, импорта доверия и входа по сертификату не должно быть.

  2. Отрицательный опыт в своей VM: измените один байт копии собственного ca.pem, не меняя манифест. Должно отказать на SHA256 до конструкторов сертификатов. Для следующего полноценного опыта создайте новый UUID-комплект вместо восстановления/перезаписи старого.

  3. Введите другой UUID, неверный пароль, пустое поле, либо удалите только свой client.p12: результат не подтверждается и поле пароля очищается. Конструктор может читать источник лениво; совпадение имени и создание профиля сами по себе не доказывают, что пароль принят во время будущего handshake.

  4. Для проверки контекста откройте свою обработку тонким клиентом: учебная команда должна отказать до синхронного хеширования. Изменение имени конфигурации или появление расширения также должно остановить опыт. Не снимайте проверки ради рабочего компьютера.

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

Свой RSA-клиентский ключ и CA подготовлены отдельным скриптом, три файла связаны UUID/контрольными суммами, в1С собран и проверен файловый TLS-паспорт. Сеть, доверие удаленному серверу, отзыв, валидность цепочки во время соединения и mTLS-авторизация не подтверждаются этим офлайн-этапом.

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

  1. Публичный сертификат без private key не годится для СертификатКлиентаФайл. Установленная8.5 выбирает PKCS12 по .PFX/.P12, PEM по .PEM, прочее по умолчанию PEM. Внутренний PXF КриптоПро не поддерживается. Не переименовывайте формат ради обхода ошибки.

  2. Скрипт использует BestAvailableEncryption и не понижает защиту до устаревших3DES/SHA1 ради совместимости. Поддержку полученного PKCS12 именно установленным OpenSSL1С надо подтвердить вручную. При несовместимости прекращайте опыт, не считайте паспорт доказательством чтения ключа. Пароль PKCS12 по официальной документации не является надежной границей безопасности; защита VM/каталога обязательна.

  3. Семидневная действительность, CLOCK/UTC, цепочка и отзыв не проверяются чтением ИмяФайла или manifest.expires_utc. Время запуска скрипта и1С должно быть корректным. CA-ключ намеренно не сохранен: этот комплект нельзя использовать для выпуска настоящих серверных/пользовательских сертификатов позже.

  4. Проверки размера/SHA и конструкторы читают файл отдельно: это не атомарная защита от подмены между чтениями. В отдельной VM не должно быть других процессов, меняющих собственный каталог. UUID/маркер — ограничение учебного workflow, не подтверждение владельца против злоумышленника.

  5. Ничего здесь не генерировалось и в1С не запускалось. Python-блок только скомпилирован/статически проверен; реальные ключи, файлы, хранилища и handshake не создавались и не выполнялись нами. После ручной подготовки комплект содержит секрет: не отправляйте client.p12, пароль и память отладчика в чат/репозиторий.

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

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

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

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

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