Utrzymanie tego samego klucza prywatnego w głównym urzędzie certyfikacji umożliwia dalsze sprawdzanie poprawności wszystkich certyfikatów względem nowego katalogu głównego; wszystko, czego potrzebujesz, to zaufać nowemu rootowi.
Relacja podpisywania certyfikatów opiera się na sygnaturze z klucza prywatnego; utrzymywanie tego samego klucza prywatnego (i domyślnie tego samego klucza publicznego) podczas generowania nowego certyfikatu publicznego, z nowym okresem ważności i wszelkimi innymi nowymi atrybutami zmienianymi w razie potrzeby, utrzymuje relację zaufania na miejscu. Listy CRL również mogą przechodzić ze starego certyfikatu do nowego, ponieważ są one, podobnie jak certyfikaty, podpisane przez klucz prywatny.
Sprawdźmy!
Utwórz główny urząd certyfikacji:
openssl req -new -x509 -keyout root.key -out origroot.pem -days 3650 -nodes
Wygeneruj z niego certyfikat podrzędny:
openssl genrsa -out cert.key 1024
openssl req -new -key cert.key -out cert.csr
Podpisz certyfikat dziecka:
openssl x509 -req -in cert.csr -CA origroot.pem -CAkey root.key -create_serial -out cert.pem
rm cert.csr
Wszystko ustawione, normalna relacja certyfikatu. Sprawdźmy zaufanie:
# openssl verify -CAfile origroot.pem -verbose cert.pem
cert.pem: OK
Ok, powiedzmy teraz, że minęło 10 lat. Wygenerujmy nowy certyfikat publiczny z tego samego głównego klucza prywatnego.
openssl req -new -key root.key -out newcsr.csr
openssl x509 -req -days 3650 -in newcsr.csr -signkey root.key -out newroot.pem
rm newcsr.csr
I .. czy to zadziałało?
# openssl verify -CAfile newroot.pem -verbose cert.pem
cert.pem: OK
Ale dlaczego? To różne pliki, prawda?
# sha1sum newroot.pem
62577e00309e5eacf210d0538cd79c3cdc834020 newroot.pem
# sha1sum origroot.pem
c1d65a6cdfa6fc0e0a800be5edd3ab3b603e1899 origroot.pem
Tak, ale to nie znaczy, że nowy klucz publiczny nie kryptograficznie pasuje do podpisu na certyfikacie. Różne numery seryjne, ten sam moduł:
# openssl x509 -noout -text -in origroot.pem
Serial Number:
c0:67:16:c0:8a:6b:59:1d
...
RSA Public Key: (1024 bit)
Modulus (1024 bit):
00:bd:56:b5:26:06:c1:f6:4c:f4:7c:14:2c:0d:dd:
3c:eb:8f:0a:c0:9d:d8:b4:8c:b5:d9:c7:87:4e:25:
8f:7c:92:4d:8f:b3:cc:e9:56:8d:db:f7:fd:d3:57:
1f:17:13:25:e7:3f:79:68:9f:b5:20:c9:ef:2f:3d:
4b:8d:23:fe:52:98:15:53:3a:91:e1:14:05:a7:7a:
9b:20:a9:b2:98:6e:67:36:04:dd:a6:cb:6c:3e:23:
6b:73:5b:f1:dd:9e:70:2b:f7:6e:bd:dc:d1:39:98:
1f:84:2a:ca:6c:ad:99:8a:fa:05:41:68:f8:e4:10:
d7:a3:66:0a:45:bd:0e:cd:9d
# openssl x509 -noout -text -in newroot.pem
Serial Number:
9a:a4:7b:e9:2b:0e:2c:32
...
RSA Public Key: (1024 bit)
Modulus (1024 bit):
00:bd:56:b5:26:06:c1:f6:4c:f4:7c:14:2c:0d:dd:
3c:eb:8f:0a:c0:9d:d8:b4:8c:b5:d9:c7:87:4e:25:
8f:7c:92:4d:8f:b3:cc:e9:56:8d:db:f7:fd:d3:57:
1f:17:13:25:e7:3f:79:68:9f:b5:20:c9:ef:2f:3d:
4b:8d:23:fe:52:98:15:53:3a:91:e1:14:05:a7:7a:
9b:20:a9:b2:98:6e:67:36:04:dd:a6:cb:6c:3e:23:
6b:73:5b:f1:dd:9e:70:2b:f7:6e:bd:dc:d1:39:98:
1f:84:2a:ca:6c:ad:99:8a:fa:05:41:68:f8:e4:10:
d7:a3:66:0a:45:bd:0e:cd:9d
Przejdźmy trochę dalej, aby sprawdzić, czy działa on w sprawdzaniu poprawności certyfikatów w świecie rzeczywistym.
Uruchom instancję Apache i spróbujmy (struktura pliku debian, dostosuj w razie potrzeby):
# cp cert.pem /etc/ssl/certs/
# cp origroot.pem /etc/ssl/certs/
# cp newroot.pem /etc/ssl/certs/
# cp cert.key /etc/ssl/private/
Ustawimy te dyrektywy na VirtualHost
nasłuchiwanie na 443 - pamiętaj, że newroot.pem
certyfikat główny nawet nie istniał, kiedy cert.pem
został wygenerowany i podpisany.
SSLEngine on
SSLCertificateFile /etc/ssl/certs/cert.pem
SSLCertificateKeyFile /etc/ssl/private/cert.key
SSLCertificateChainFile /etc/ssl/certs/newroot.pem
Sprawdźmy, jak widzi to openssl:
# openssl s_client -showcerts -CAfile newroot.pem -connect localhost:443
Certificate chain
0 s:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=server.lan
i:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=root
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
1 s:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=root
i:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=root
-----BEGIN CERTIFICATE-----
MIICHzCCAYgCCQCapHvpKw4sMjANBgkqhkiG9w0BAQUFADBUMQswCQYDVQQGEwJB
...
-----END CERTIFICATE-----
(this should match the actual contents of newroot.pem)
...
Verify return code: 0 (ok)
Ok, a co z przeglądarką korzystającą z kryptograficznego interfejsu API MS? Najpierw zaufaj rootowi, potem wszystko będzie dobrze, z numerem seryjnym nowego roota:
I powinniśmy nadal pracować ze starym rootem. Przełącz konfigurację Apache wokół:
SSLEngine on
SSLCertificateFile /etc/ssl/certs/cert.pem
SSLCertificateKeyFile /etc/ssl/private/cert.key
SSLCertificateChainFile /etc/ssl/certs/origroot.pem
Wykonaj pełny restart na Apache, przeładowanie nie przełączy poprawnie certyfikatów.
# openssl s_client -showcerts -CAfile origroot.pem -connect localhost:443
Certificate chain
0 s:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=server.lan
i:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=root
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
1 s:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=root
i:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=root
-----BEGIN CERTIFICATE-----
MIIC3jCCAkegAwIBAgIJAMBnFsCKa1kdMA0GCSqGSIb3DQEBBQUAMFQxCzAJBgNV
...
-----END CERTIFICATE-----
(this should match the actual contents of origroot.pem)
...
Verify return code: 0 (ok)
A dzięki przeglądarce MS crypto API Apache prezentuje stary katalog główny, ale nowy katalog główny nadal znajduje się w zaufanym magazynie głównym komputera. Automatycznie go znajdzie i zweryfikuje certyfikat względem zaufanego (nowego) katalogu głównego, mimo że Apache prezentuje inny łańcuch (stary katalog główny). Po usunięciu nowego katalogu głównego z zaufanych katalogów głównych i dodaniu oryginalnego certyfikatu głównego wszystko jest w porządku:
Więc to jest to! Zachowaj ten sam klucz prywatny podczas odnawiania, zamień w nowym zaufanym katalogu głównym, a prawie wszystko działa . Powodzenia!