HTTPS: доверие сертификату и проверка имени сервера
Безопасные TlsOptions, собственный CA, ошибки имени/срока/цепочки и готовый C#-клиент.
Обычный HTTPS
HTTPS-адрес включает шифрование, но клиенту также нужны доверенная цепочка сертификатов и правильное имя сервера. CA — центр сертификации, чьим сертификатом подтверждают доверие цепочке. HttpRequest по умолчанию создаёт проверяющий TlsOptions.Client; HttpClient должен получить такие параметры явно либо распознать схему https. Пример HttpClient выбирает Client для https автоматически в своём коде.
Для сервера с общедоверенным сертификатом оставьте CaPath пустым. Для собственного CA передайте его PEM-файл через TlsTrust. Это открытый сертификат доверия; закрытый ключ сервера в игру не копируется. Собственный набор CA используется вместо стандартного набора для этого соединения, а не автоматически добавляется к нему.
Подключить свой сервер
Нужен работающий HTTPS API с ответом {"message":"текст"} и сертификатом, подходящим к имени/IP в URL. Обычный LocalHttpFixture.py обслуживает HTTP и сам по себе не создаёт HTTPS.
- Возьмите HttpJsonRequest.cs из руководства HTTP, добавьте TlsTrust.cs и TlsJsonDemo.cs.
- Прикрепите TlsJsonDemo к Entity отдельного уровня. В Inspector задайте Url своего HTTPS API. Для собственного CA положите PEM, например в
asset://certs/dev-ca.pem, и укажите CaPath. Для стандартного доверия оставьте CaPath пустым. - Соберите и запустите F6. Ожидаются transport=Success, status=200 и сообщение. При ошибке загрузки CA пример завершает запуск; он не переключается на отключённую проверку.
TlsTrust.cs
using Reckfell;
public partial class TlsTrust : Entity
{
public static Error LoadCustomCa(string path, out TlsOptions? options)
{
options = null;
if (!FileAccess.FileExists(path)) return Error.FileNotFound;
using var certificate = new X509Certificate();
Error error = certificate.Load(path);
if (error != Error.Ok) return error;
options = TlsOptions.Client(certificate); return Error.Ok;
}
}TlsJsonDemo.cs
using System;
using Reckfell;
public partial class TlsJsonDemo : Entity
{
[Export] public string Url { get; set; } = "https://127.0.0.1:8766/message";
[Export] public string CaPath { get; set; } = "";
public override void _Ready()
{
if (!Uri.TryCreate(Url, UriKind.Absolute, out Uri? uri) || uri.Scheme != "https")
{ ReckfellApi.Print("HTTPS requires an https:// URL"); return; }
TlsOptions? trust = null;
if (CaPath.Length != 0)
{
Error loaded = TlsTrust.LoadCustomCa(CaPath, out trust);
if (loaded != Error.Ok) { ReckfellApi.Print($"TLS CA: {loaded}"); return; }
}
var api = new HttpJsonRequest { Trust = trust }; AddChild(api);
api.Completed += reply => ReckfellApi.Print($"HTTPS: transport={reply.Transport}, status={reply.StatusCode}, failure={reply.Failure}, message={reply.Message}");
Error start = api.Start(Url);
if (start != Error.Ok) ReckfellApi.Print($"HTTPS start: {start}");
}
}Какие проверки сохраняются
TlsOptions.Client(certificate) сохраняет проверку сертификата и имени. SAN — расширение сертификата со списком допустимых имён и IP-адресов. Сертификат для api.example.com не обязан подходить для адреса сервера по IP: этот IP должен быть указан в SAN. Изменение hosts/маршрута не делает чужое имя доверенным.
commonNameOverride задаёт другую ожидаемую идентичность для специально спроектированного подключения. Это не общий способ исправить ошибку имени: не копируйте произвольную строку из ошибки/ответа сервера. В обычном клиенте исправьте URL, сертификат или настройки маршрутизации.
ClientUnsafe отключает проверку имени. Без trustedChain он отключает и обязательную проверку доверия цепочке; с заданной цепочкой её проверка остаётся, но правильное имя всё равно не подтверждается. В опубликованных примерах ClientUnsafe не используется.
Разобрать ошибку
| Результат | Что проверить |
|---|---|
| Error при загрузке CA | Путь, наличие PEM и формат сертификата; этот файл не является приватным ключом |
| CantResolve / CantConnect / Timeout | DNS, маршрут, порт, работу сервера и доступность соединения; тайм-аут сам по себе не доказывает ошибку сертификата |
| TlsHandshakeError | Диагностику движка, имя/SAN, доверенную цепочку, сроки действия, время системы и поддерживаемые протоколы |
| Success + HTTP 401/403 | TLS мог пройти; авторизация приложения проверяется отдельно |
| Success + ошибка JSON/schema | TLS и HTTP не гарантируют нужный формат данных |
Сначала добейтесь корректного имени и доверия. Не исправляйте отказ отключением проверки сертификата. Корневой CA сам по себе не заменяет правильно настроенную цепочку сервера. После обновления/замены сертификата повторяйте проверку клиента и целевого экспорта.
Если соединение по имени зависает, сравните разрешённые IPv4/IPv6-адреса и доступность сервера по каждому из них. Диагностика по IP сохраняет требование подходящего IP SAN или заранее выбранного проверяемого имени. Тайм-аут localhost наблюдался на проверочном Windows-стенде даже для HTTP; его причина не установлена, и этот путь не считается проверенным подключением.
В локальной проверке применяются IPv4-адрес и отдельные тестовые сертификаты с подходящим IP SAN: правильное доверие даёт ответ; недоверенная цепочка, ошибочное ожидаемое имя через commonNameOverride и истёкший сертификат отклоняются. Это не проверка всех публичных CA, DNS/IPv6-подключений, прокси, автоматического обновления, систем доверия других платформ или готового экспорта. Настройку сервера и защиту токенов проверяйте отдельно; клиентские параметры TLS не создают систему учётных записей.