Dwa certyfikaty CA mogą mieć ten sam klucz publiczny i ten sam subject, a mimo to nie być wymienne. Jeden jest samopodpisany, drugi podpisany krzyżowo przez stary korzeń, a ich nazwy wystawcy, numery seryjne i podpisy się różnią. Liść może związać się konkretnie z jednym z nich przez swój Authority Key Identifier. To powiązanie pozostaje niewidoczne, dopóki klient nie wybierze złego łańcucha i handshake nie zawiedzie bez oczywistej przyczyny.

Wykonaj te pięć kontroli po kolei: każda wyklucza inną awarię.

Kontrola 1: narysuj oba łańcuchy, zanim dotkniesz szablonu

Zapisz ścieżki. Stara populacja ufa Staremu korzeniowi A, który wydał CA B, a ta wydała liść serwera. Nowa populacja ufa samopodpisanemu CA B bezpośrednio. Oba certyfikaty B niosą ten sam klucz i subject, i właśnie dlatego osoba czytająca wiersz subject widzi jeden CA tam, gdzie klient widzi dwa.

Kopia podpisana krzyżowo też musi być prawdziwym certyfikatem CA, z basic constraints i key usage pozwalającymi podpisywać.

Kontrola 2: porównaj pola AKI, nie tylko klucz

Nazwa wystawcy liścia musi odpowiadać subjectowi B, i ta część zwykle się trzyma. Authority Key Identifier to miejsce, w którym obie kopie się rozchodzą, bo może nieść identyfikator klucza, certyfikat wystawcy i numer seryjny. Identyfikator klucza pasuje do obu kopii, ponieważ klucz jest identyczny. Pola wystawcy i numeru seryjnego pasują dokładnie do jednej, dlatego łańcuch budowany przeciw kopii samopodpisanej może zawieść przeciw podpisanej krzyżowo.

Zbadaj liść zamiast zgadywać: openssl x509 -in server.pem -noout -ext authorityKeyIdentifier.

Następnie porównaj oba kandydatów za pomocą openssl x509 -in b-cross.pem -noout -text | grep -A2 "Authority Key Identifier", i to samo polecenie przeciw kopii samopodpisanej.

Jeśli liść niesie wystawcę i numer seryjny, łańcuch ukończy tylko certyfikat opisany tymi wartościami, niezależnie od tego, którą kopię klient załadował.

Kontrola 3: zmieniaj politykę wydawania, nigdy podpisanych bajtów

Rozszerzenia żyją wewnątrz podpisu. Dodanie, usunięcie lub edycja jednego na istniejącym liściu nie jest naprawą, to inny certyfikat i wymaga ponownego wydania. Zmiana należy do polityki wydawania: authorityKeyIdentifier = keyid,issuer:always sprawia, że nowe liście noszą powiązanie specyficzne dla certyfikatu, a sam keyid zachowuje luźniejszą formę odpowiednią dla zamierzonego przejścia na podpisywanie krzyżowe. Zdecyduj, czego chce twoje PKI, zanim zostanie podpisana następna partia.

Edycja wspólnego szablonu zmienia też każdy przyszły certyfikat, nie tylko serwer przed tobą.

Kontrola 4: weryfikuj każdą populację zaufania osobno

Przetestuj starą ścieżkę i nową ścieżkę jako osobne przebiegi. openssl verify -purpose sslserver -verify_hostname vpn.example -CAfile old-root.pem -untrusted b-cross-signed.pem server.pem ćwiczy trasę podpisaną krzyżowo, a to samo polecenie z nowym korzeniem i bez pliku untrusted ćwiczy trasę samopodpisaną. Mieszanie obu korzeni w jednym pakiecie ukrywa, który łańcuch został wybrany. Powtórz potem z prawdziwymi klientami, bo backend VPN może preferować łańcuch albo przypiąć certyfikat w sposób, którego openssl nie wykonuje.

Dostarcz certyfikat pośredni przez konfigurację usługi, którą klient naprawdę czyta, a nie przez stronę wiki.

Kontrola 5: trzymaj starą ścieżkę na zegarze wycofania

Podpisywanie krzyżowe utrzymuje starą ścieżkę zaufania przy życiu z założenia, co jest jednocześnie celem i ryzykiem. Nie naprawia przejętego starego korzenia i nie usuwa tego korzenia z żadnego klienta. Zapisz, kiedy stara ścieżka przestanie dawać zaufanie, i potwierdź, że ten dzień naprawdę nadejdzie.

Jeśli każdy klient może przyjąć nowy korzeń, zanim liście się przesuną, zwykłe wdrożenie z podwójnym zaufaniem jest prostsze niż podpisywanie krzyżowe, i zostawia o jedną rzecz mniej do wycofania.

Powiązane artykuły