Кросс-подписанный CA: ключ совпадает, привязка AKI — нет
Лист может закрепить своего издателя через идентификатор ключа вместе с издателем и серийным номером. Проверьте эту привязку, прежде чем считать кросс-подписанную цепочку взаимозаменяемой.
Два сертификата CA могут иметь один и тот же открытый ключ и один и тот же subject и всё же не быть взаимозаменяемыми. Один самоподписанный, другой кросс-подписан старым корнем, и их имена издателя, серийные номера и подписи различаются. Лист может привязаться именно к одному из них через свой Authority Key Identifier. Эта привязка остаётся невидимой, пока клиент не выберет неверную цепочку и handshake не завершится неудачей без видимой причины.
Выполните эти пять проверок по порядку: каждая исключает свой тип отказа.
Проверка 1: нарисуйте обе цепочки, прежде чем трогать шаблон
Запишите пути. Старая популяция доверяет Старому корню A, который выпустил CA B, который выпустил лист сервера. Новая популяция доверяет самоподписанному CA B напрямую. Оба сертификата B несут один и тот же ключ и subject, и именно поэтому человек, читающий строку subject, видит один CA там, где клиент видит два.
Кросс-подписанная копия тоже должна быть настоящим сертификатом CA, с basic constraints и key usage, разрешающими подпись.
Проверка 2: сравните поля AKI, а не только ключ
Имя издателя листа должно совпадать с subject B, и эта часть обычно держится. Authority Key Identifier — это место, где две копии расходятся, потому что он может нести идентификатор ключа, сертификат издателя и серийный номер. Идентификатор ключа совпадает с обеими копиями, так как ключ идентичен. Поля издателя и серийного номера совпадают ровно с одной, и поэтому цепочка, построенная против самоподписанной копии, может не пройти против кросс-подписанной.
Изучите лист вместо догадок: openssl x509 -in server.pem -noout -ext authorityKeyIdentifier.
Затем сравните обоих кандидатов с помощью openssl x509 -in b-cross.pem -noout -text | grep -A2 "Authority Key Identifier" и ту же команду против самоподписанной копии.
Если лист несёт издателя и серийный номер, цепочку завершает только тот сертификат, который описывают эти значения, какую бы копию клиент ни загрузил.
Проверка 3: меняйте политику выпуска, а не подписанные байты
Расширения живут внутри подписи. Добавление, удаление или правка одного из них в существующем листе — это не ремонт, это другой сертификат, и он требует перевыпуска. Изменение относится к политике выпуска: authorityKeyIdentifier = keyid,issuer:always заставляет новые листы нести привязку, специфичную для сертификата, а один keyid сохраняет более свободную форму, подходящую для намеренного перехода на кросс-подпись. Решите, что нужно вашей PKI, прежде чем будет подписан следующая партия.
Правка общего шаблона меняет и каждый будущий сертификат, а не только сервер перед вами.
Проверка 4: проверяйте каждую популяцию доверия отдельно
Проверяйте старый путь и новый путь отдельными запусками. openssl verify -purpose sslserver -verify_hostname vpn.example -CAfile old-root.pem -untrusted b-cross-signed.pem server.pem упражняет кросс-подписанный маршрут, а та же команда с новым корнем и без untrusted-файла упражняет самоподписанный маршрут. Смешивание обоих корней в одном наборе скрывает, какая цепочка была выбрана. Затем повторите с настоящими клиентами, потому что VPN-бэкенд может предпочитать цепочку или закреплять сертификат способами, которых openssl не делает.
Доставляйте промежуточный сертификат через конфигурацию службы, которую клиент действительно читает, а не через вики-страницу.
Проверка 5: держите старый путь на часах вывода из эксплуатации
Кросс-подпись по замыслу поддерживает старый путь доверия живым, и это одновременно цель и риск. Она не устраняет скомпрометированный старый корень и не удаляет этот корень ни из одного клиента. Запишите, когда старый путь перестанет давать доверие, и подтвердите, что этот день действительно наступит.
Если каждый клиент может принять новый корень до перемещения листов, простая раскатка с двойным доверием проще кросс-подписи, и она оставляет на одну вещь меньше для вывода из эксплуатации.