Перейти к содержанию

Сертификат X.509

Сервер предъявляет сертификат, и прошивка должна решить, верить ли ему: проверить подпись цепочки до корневого сертификата из флеш, сверить имя и убедиться, что срок действия не истёк. Последнее невозможно без часов — отсюда связка TLS и SNTP на любом контроллере.

Обновлено Редакция GAW

Сертификат X.509 — подписанный удостоверяющим центром (CA) документ, который связывает открытый ключ с именем его владельца на заданный срок действия. Профиль для интернета задаёт RFC 5280; именно такие сертификаты сервер предъявляет клиенту в рукопожатии TLS, а клиент решает, доверять ли ему, проверяя цепочку подписей до корневого сертификата из собственного хранилища.

Что внутри

По RFC 5280 (разд. 4.1) сертификат состоит из трёх частей: tbsCertificate — подписываемые данные, signatureAlgorithm — алгоритм подписи и signatureValue — сама подпись CA. Подписываемые данные кодируются по правилам DER; то, что обычно лежит в файле .pem, — это тот же DER, записанный в Base64.

Поле tbsCertificateНазначение (RFC 5280)
versionверсия; при расширениях обязана быть 3 (разд. 4.1.2.1)
serialNumberположительное целое, уникальное у данного CA, до 20 октетов (разд. 4.1.2.2)
issuerимя удостоверяющего центра
validitynotBefore и notAfter, срок включительно (разд. 4.1.2.5)
subjectимя владельца
subjectPublicKeyInfoалгоритм и открытый ключ
extensionssubjectAltName с DNS-именем или IP-адресом, basicConstraints с флагом cA, keyUsage, extendedKeyUsage

Даты до 2049 года включительно записываются типом UTCTime (двузначный год), с 2050-го — GeneralizedTime; обе — по Гринвичу и с секундами. Для устройств, которым нельзя назначить разумный срок, RFC рекомендует notAfter = 99991231235959Z. Подпись покрывает дайджест данных от хеш-функции, поэтому изменить хоть байт в сертификате, не владея ключом CA, нельзя.

Цепочка и якорь доверия

Клиент редко хранит сертификат конкретного сервера. Он хранит якорь доверия — корневой сертификат CA — и проверяет путь сертификации (разд. 6.1): последовательность, в которой субъект каждого сертификата является издателем следующего, первый выпущен якорем доверия, последний — проверяемый, и все действительны на момент проверки. Сам якорь в путь не входит, а его выбор RFC называет вопросом политики: для прошивки это ответ на вопрос, какие корни положить во флеш. Для каждого звена проверяются подпись, срок, отсутствие отзыва и имя издателя (разд. 6.1.3), а сертификат с неизвестным критическим расширением обязаны отвергнуть. Промежуточный CA должен иметь basicConstraints с флагом cA, иначе его ключом нельзя подписывать другие сертификаты (разд. 4.2.1.9).

На микроконтроллере

Две практические трудности — хранилище корней и время. ESP-IDF встраивает в прошивку пакет корневых сертификатов из хранилища Mozilla NSS: полный, более 130 штук, или фильтр примерно из 38 самых распространённых, покрывающих около 93 % использования; во флеш попадают только имя субъекта и открытый ключ каждого корня, а обновляется пакет вместе с приложением при обновлении по воздуху. В ESP-TLS сервер проверяют через cacert_buf, глобальное хранилище CA или crt_bundle_attach, а поле common_name задаёт имя для SNI и сверки с сертификатом.

Проверка срока действия в mbedTLS на ESP32 включается опцией CONFIG_MBEDTLS_HAVE_TIME_DATE — по умолчанию она выключена, и даты сертификата игнорируются. При включении прошивка обязана выставить системные часы до первого соединения: документация рекомендует SNTP, а неверное время даёт ошибки MBEDTLS_X509_BADCERT_FUTURE или MBEDTLS_X509_BADCERT_EXPIRED. Если точного времени нет — нет сети до самого TLS или сервер времени недоступен, — помогают часы реального времени с батарейным питанием, но Espressif отдельно предупреждает о двух ловушках: корневые сертификаты могут истечь, пока устройство лежит офлайн, а сбой SNTP оставляет время неверным надолго после сброса. Когда клиентов и серверов немного и обе стороны настраиваются вручную, от сертификатов отказываются в пользу TLS-PSK.

Частые вопросы

Что проверяет клиент, получив сертификат сервера?

По RFC 5280 (разд. 6.1.3) для каждого сертификата в цепочке — что подпись проверяется открытым ключом издателя, что текущее время попадает в срок действия, что сертификат не отозван и что имя издателя совпадает с субъектом предыдущего. Цепочка должна начинаться с сертификата, выпущенного якорем доверия, — корневым сертификатом, который хранится у клиента. Сверх этого клиент TLS сопоставляет имя сервера с subjectAltName; в ESP-TLS за это отвечает поле common_name при skip_common_name = false.

Почему микроконтроллеру для TLS нужно знать время?

Потому что проверка срока действия сравнивает notBefore и notAfter с текущим временем. После сброса часы контроллера показывают 1970 год или случайное значение, и сертификат окажется «ещё не действителен» или «просрочен». В ESP-IDF проверка включается опцией CONFIG_MBEDTLS_HAVE_TIME_DATE (по умолчанию выключена, даты игнорируются), и документация требует выставить часы до первого TLS-соединения, рекомендуя SNTP; ошибки — MBEDTLS_X509_BADCERT_FUTURE и MBEDTLS_X509_BADCERT_EXPIRED.

Сколько живёт сертификат и что будет, когда он истечёт?

Срок задаёт издатель в полях notBefore и notAfter, обе границы включительно. У сертификатов устройств, которым разумный срок назначить нельзя, RFC 5280 рекомендует notAfter = 99991231235959Z, то есть «бессрочно». Для прошивки опаснее истечение не серверного, а корневого сертификата из флеш: Espressif предупреждает, что все доверенные сертификаты могут истечь, пока устройство офлайн, и тогда соединение для обновления не установится. Поэтому пакет корневых сертификатов обновляют вместе с прошивкой по OTA.

Источники

  1. IETF. RFC 5280 Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile. D. Cooper et al., May 2008 — разд. 4.1: Certificate = tbsCertificate, signatureAlgorithm, signatureValue; подписываемые данные кодируются DER; TBSCertificate содержит version, serialNumber, signature, issuer, validity (notBefore, notAfter), subject, subjectPublicKeyInfo, необязательные идентификаторы и extensions (только в v3); разд. 4.1.2.1: при наличии расширений версия обязана быть 3 (значение 2), реализации обязаны принимать v3; разд. 4.1.2.2: серийный номер — положительное целое, уникальное у данного CA, пользователи обязаны принимать номера до 20 октетов; разд. 4.1.2.5: срок действия — от notBefore до notAfter включительно, даты до 2049 года кодируются UTCTime, с 2050 — GeneralizedTime, обе в Гринвиче с секундами; для устройств без разумного срока notAfter следует задавать 99991231235959Z; разд. 4.2.1.6: subjectAltName — DNS-имя, IP-адрес, URI, e-mail; разд. 4.2.1.9: basicConstraints с флагом cA и pathLenConstraint; разд. 4.2.1.12: extendedKeyUsage — назначения ключа, обычно в сертификатах конечных субъектов; разд. 6.1: путь сертификации — последовательность, где субъект сертификата x является издателем x+1, первый выпущен якорем доверия, последний — проверяемый, и каждый действителен на момент проверки; якорь доверия (самоподписанный сертификат) в путь не входит, его выбор — вопрос политики; разд. 6.1.3 (a): проверяются подпись, попадание текущего времени в срок действия, отсутствие отзыва, имя издателя; клиенты обязаны отвергать сертификат с неподдерживаемым критическим расширением
  2. Espressif. ESP-IDF Programming Guide v6.1, ESP32: Configuration Options Reference (Component config > mbedTLS); ESP x509 Certificate Bundle; ESP-TLS — CONFIG_MBEDTLS_HAVE_TIME_DATE — проверка срока действия сертификатов X.509 в mbedTLS, по умолчанию выключена: поля valid from и valid to игнорируются; при включении сравниваются с системным временем через time() и gmtime(), при несовпадении проверка завершается кодами MBEDTLS_X509_BADCERT_FUTURE или MBEDTLS_X509_BADCERT_EXPIRED; прошивка обязана выставить часы до использования TLS, рекомендуемый способ — SNTP; оговорка: все доверенные сертификаты могут истечь, пока устройство офлайн, а сбой SNTP оставит время неверным надолго; CONFIG_MBEDTLS_HAVE_TIME — относительное время для истечения билетов сеанса, верных часов не требует; страница ESP x509 Certificate Bundle: пакет корневых сертификатов из хранилища Mozilla NSS — полный более 130 сертификатов (обновлён 11 февраля 2026) или фильтр около 38 самых распространённых (около 93 % использования), в двоичный файл встраиваются имя субъекта и открытый ключ, пакет обновляется вместе с приложением по OTA; ESP-TLS: сервер проверяют по cacert_buf, глобальному хранилищу CA или crt_bundle_attach, поле common_name задаёт имя для SNI и сверки с сертификатом, skip_common_name = false
Страница помогла?

Нашли ошибку? ·