Два сертифікати 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: тримайте старий шлях на годиннику виведення з експлуатації

Крос-підпис за задумом підтримує старий шлях довіри живим, і це водночас мета й ризик. Він не усуває скомпрометований старий корінь і не вилучає цей корінь з жодного клієнта. Запишіть, коли старий шлях перестане давати довіру, і підтвердьте, що той день справді настане.

Якщо кожен клієнт може прийняти новий корінь до переміщення листів, просте розгортання з подвійною довірою простіше за крос-підпис, і воно залишає на одну річ менше для виведення.

Схожі статті