Закінчення терміну дії та відновлення кореневого сертифіката органу сертифікації


96

У 2004 році я створив невеликий орган сертифікації, використовуючи OpenSSL в Linux та прості сценарії управління, що надаються OpenVPN. Відповідно до настанов, які я знайшов у той час, я встановив термін дії кореневого сертифіката CA 10 років. З тих пір я підписав багато сертифікатів на тунелі, веб-сайти та сервери електронної пошти OpenVPN, усі вони також мають термін дії 10 років (це, можливо, було неправильно, але я тоді не знав кращого).

Я знайшов багато посібників щодо створення КА, але лише дуже мало інформації про його управління, зокрема, про те, що потрібно зробити, коли закінчиться термін дії сертифіката кореневого ЦС, що станеться через деякий час у 2014 році. Отже, у мене є наступне питання:

  • Чи стануть сертифікати, термін дії яких продовжується після закінчення терміну дії кореневого сертифіката CA, недійсними, як тільки термін дії останнього закінчується, або вони продовжуватимуть діяти (оскільки вони були підписані протягом періоду дії сертифіката ЦО)?
  • Які операції необхідні для поновлення кореневого сертифіката ЦС та забезпечення плавного переходу через його закінчення?
    • Чи можу я якось повторно підписати поточний кореневий сертифікат CA з іншим терміном дії та завантажити новопідписаний сертифікат клієнтам, щоб сертифікати клієнтів залишалися дійсними?
    • Або мені потрібно замінити всі клієнтські сертифікати на нові, підписані новим кореневим сертифікатом CA?
  • Коли слід поновити кореневий сертифікат CA? Близький до закінчення терміну чи розумний час до закінчення терміну дії?
  • Якщо оновлення кореневого сертифіката CA стане важливою роботою, що я можу зробити краще зараз, щоб забезпечити більш плавний перехід під час наступного оновлення (звичайно, якщо встановити термін дії до 100 років, звичайно)?

Ситуація трохи ускладнюється тим, що мій єдиний доступ до деяких клієнтів - через тунель OpenVPN, який використовує сертифікат, підписаний поточним сертифікатом CA, тому якщо мені доведеться замінити всі сертифікати клієнта, мені потрібно буде скопіювати нові файли для клієнта, перезапустіть тунель, схрестіть мені пальці і сподіваюся, що він з’явиться згодом.

Відповіді:


142

Утримуючи той самий приватний ключ у вашому кореневому сервері, CA дозволяє всі сертифікати продовжувати успішну перевірку щодо нового кореня; все, що потрібно від вас, - це довіряти новому корінню.

Відносини підписання сертифіката засновані на підписі з приватного ключа; зберігання одного і того ж приватного ключа (і, по суті, одного і того ж відкритого ключа) при створенні нового публічного сертифіката, з новим терміном дії та будь-якими іншими новими атрибутами, зміненими в міру необхідності, зберігає довірчі відносини. CRL також можуть продовжуватися від старого сертифіката до нового, оскільки вони, як сертифікати, підписуються приватним ключем.


Отже, давайте перевіримо!

Створіть кореневий CA:

openssl req -new -x509 -keyout root.key -out origroot.pem -days 3650 -nodes

Створіть з нього свідоцтво про дитину:

openssl genrsa -out cert.key 1024
openssl req -new -key cert.key -out cert.csr

Підпишіть дитину cert:

openssl x509 -req -in cert.csr -CA origroot.pem -CAkey root.key -create_serial -out cert.pem
rm cert.csr

Все там встановлено, нормальне відношення сертифіката Перевіримо довіру:

# openssl verify -CAfile origroot.pem -verbose cert.pem
cert.pem: OK

Добре, так, зараз скажімо, пройшло 10 років. Давайте генеруємо новий публічний сертифікат з того самого кореневого приватного ключа.

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

І .. це спрацювало?

# openssl verify -CAfile newroot.pem -verbose cert.pem
cert.pem: OK

Але чому? Вони різні файли, правда?

# sha1sum newroot.pem
62577e00309e5eacf210d0538cd79c3cdc834020  newroot.pem
# sha1sum origroot.pem
c1d65a6cdfa6fc0e0a800be5edd3ab3b603e1899  origroot.pem

Так, але це не означає, що новий відкритий ключ не криптографічно відповідає підпису в сертифікаті. Різні серійні номери, однаковий модуль:

# 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

Давайте підемо трохи далі, щоб перевірити, чи працює він у реальному світі.

Запустіть екземпляр Apache, і давайте перейдемо (структура файлів debian, коригуйте за потребою):

# cp cert.pem /etc/ssl/certs/
# cp origroot.pem /etc/ssl/certs/
# cp newroot.pem /etc/ssl/certs/
# cp cert.key /etc/ssl/private/

Ми встановимо ці директиви на VirtualHostпрослуховування на 443 - пам’ятайте, newroot.pemкореневий сертифікат навіть не існував, коли cert.pemбув створений і підписаний.

SSLEngine on
SSLCertificateFile /etc/ssl/certs/cert.pem
SSLCertificateKeyFile /etc/ssl/private/cert.key
SSLCertificateChainFile /etc/ssl/certs/newroot.pem

Давайте перевіримо, як це бачить 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)

Добре, а як щодо браузера, який використовує крипто-API MS? Потрібно спочатку довірити корінь, після чого все добре, з порядковим номером нового кореня:

newroot

І ми ще повинні працювати зі старим коренем. Перемикайте конфігурацію Apache навколо:

SSLEngine on
SSLCertificateFile /etc/ssl/certs/cert.pem
SSLCertificateKeyFile /etc/ssl/private/cert.key
SSLCertificateChainFile /etc/ssl/certs/origroot.pem

Виконайте повний перезапуск Apache, перезавантаження не перемкне серти належним чином.

# 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)

І через браузер MS Crypto API, Apache представляє старий корінь, але новий корінь все ще знаходиться в надійному кореневому магазині комп'ютера. Він автоматично знайде його і перевірить сертифікат щодо довіреного (нового) кореня, незважаючи на те, що Apache представляє інший ланцюжок (старий корінь). Після вилучення нового кореня з надійних коренів та додавання оригінальної кореневої церти все добре:

корінь


Отже, це все! Зберігайте той самий приватний ключ, коли ви поновлюєте, поміняйте новим надійним коренем, і він майже все працює . Удачі!


2
У будь-якому разі, який сенс створювати новий кореневий сертифікат, якщо ви просто збираєтеся повторно використовувати той же приватний ключ? Якщо ви продовжуєте робити це знову і знову, то який сенс навіть мати термін дії сертифікату? Я подумав, що кореневий термін використовується для того, щоб змусити адміністраторів зробити новіший (швидше за все, сильніший) приватний ключ, який є більш захищеним від постійних машин, які намагаються зламати ключі. 40-бітний ключ, зроблений 20 років тому, недостатньо безпечний для
jvhashe

2
@jvhashe Якщо кореневий сертифікат вже не є достатньо міцним криптографічно, то слід позбутися від нього незалежно від терміну його дії. Якщо ви генеруєте власний корінь, ніщо не заважає вам встановити його до кінця минулих сотень років, коли ви більше не будете на планеті. Термін придатності ледве має відношення до кореневого сертифіката - а для дочірнього сертифіката закінчення терміну дії насправді не стосується і криптографічної сили (попросіть ЦС, які готуються скасувати всі 1024-бітні серти у жовтні) - див. Тут для отримання додаткової інформації.
Шейн Мадден

3
На додаток до сказаного, я виявив, що серійний номер повинен бути однаковим, щоб цей метод працював.
Скотт Преснелл

2
-set_serial 01- WTF ??? ВИ НЕ МОЖЕТЕ ВИКОРИСТОВАТИ СЕРІЙНІ НОМЕРИ . Ви навіть зверталися до RFC 4158, інфраструктури відкритих ключів Internet X.509: створення шляху сертифікації ? Або ти просто вигадуєш, коли йдеш? Ви не маєте уявлення про проблеми, які ви викликаєте в агентах користувача, коли вони починають будувати шлях.

1
@jww Ви прочитали відповідь? Це лише демонстрація того факту, що криптографія працює. Ця команда буквально просто генерує тестовий сертифікат, який ми можемо перевірити пізніше, з метою тестування взаємозв'язку старого та нового кореневого cert. Якщо хто - то є , використовуючи ці команди безпосередньо, я , звичайно , сподіваюся , що - то ламається, і вони розуміють , що вони повинні звернути увагу на контекст чого - то , перш ніж сліпо бігти воно (або відлітати ручку про те , 01є прийнятним серійним в лабораторії).
Шейн Медден

14

Я помітив, що у оновленому сертифікаті оригінального ключа CA можуть бути відсутні розширення CA. Це працювало для мене більш доречно (він створює ./renewedselfsignedca.conf, де визначено розширення V3 CA, а ca.key та ca.crt вважаються оригінальним ключем та сертифікатом CA):

openssl x509 -x509toreq -in ca.crt -signkey ca.key -out renewedselfsignedca.csr
echo -e "[ v3_ca ]\nbasicConstraints= CA:TRUE\nsubjectKeyIdentifier= hash\nauthorityKeyIdentifier= keyid:always,issuer:always\n" > renewedselfsignedca.conf
openssl x509 -req -days 1095 -in renewedselfsignedca.csr -signkey ca.key -out renewedselfsignedca.crt -extfile ./renewedselfsignedca.conf -extensions v3_ca

2
Це було надзвичайно корисним доповненням. Насправді дійсна відповідь не призводить до отримання достатньо сумісного для мене сертифіката, якщо у вас є довільні налаштування у вихідному корені ca.
Теуні

1
Друга, дуже корисна. Ще одне доповнення: як Скотт Преснелл у коментарях до прийнятої відповіді, мені також довелося вручну вказати шістнадцятковий порядковий номер оновленого сертифіката, щоб він відповідав старого. Це означало додати -set_serial 0xdeadbeefabba(не справжній серійний номер :)) до останньої команди x509. Лише тоді мої клієнтські сертифікати успішно підтверджувались відновленням оновленого сертифіката CA.
Дж. К. Лайхо

Цей спосіб простіше, оскільки він зберігає ту саму інформацію, що і попередній сертифікат.
лепе

Я створив сценарій для цього рішення плюс -set_serial - дивіться мою відповідь
Вольфганг Фаль

Ця відповідь врятувала мені багато роботи, витративши майже день на питання, яке вимагало цього, я майже збирався відмовитись, я підказав тобі свій капелюх!
Onitlikesonic

2

Основний режим для продовження терміну дії кореня (потрібен відкритий X.509 та асоційований приватний ключ):

Створіть КСВ із відкритого X.509 та приватного ключа:

openssl x509 -x509toreq -in XXX.crt -signkey XXX.key -out XXX.csr

Повторно підпишіть КСВ приватним ключем:

openssl x509 -in XXX.csr -out XXX.crt -signkey XXX.key -req -days 365

1

@Bianconiglio plus -set_serial працював на мене. Мій сервер є лише інтранет, тому я не переживаю багато, які побічні ефекти є, і в мене зараз є час попрацювати над «правильним» рішенням.

Я використовував наступний настроюваний сценарій. Просто встановіть змінні CACRT, CAKEY та NEWCA.

# WF 2017-06-30
# https://serverfault.com/a/501513/162693
CACRT=SnakeOilCA.crt
CAKEY=SnakeOilCA.key
NEWCA=SnakeOilCA2017
serial=`openssl x509 -in $CACRT -serial -noout | cut -f2 -d=`
echo $serial
openssl x509 -x509toreq -in $CACRT -signkey $CAKEY -out $NEWCA.csr
echo -e "[ v3_ca ]\nbasicConstraints= CA:TRUE\nsubjectKeyIdentifier= hash\nauthorityKeyIdentifier= keyid:always,issuer:always\n" > $NEWCA.conf
openssl x509 -req -days 3650 -in $NEWCA.csr -set_serial 0x$serial -signkey $CAKEY -out $NEWCA.crt -extfile ./$NEWCA.conf -extensions v3_ca
openssl x509 -in $NEWCA.crt -enddate -serial -noout

0

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

Ви не можете "відновити" кореневу серту. Все, що ви можете зробити - це створити нове.

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

Що стосується тунелів VPN, я створив би кілька пробних серверів для експерименту, щоб ви точно зрозуміли, що вам потрібно зробити, перш ніж робити це з машиною клієнта.


Ця відповідь, схоже, говорить про те, що можна відновити кореневий сертифікат, повторно використовуючи його ключ. Але я підозрюю, що це нічим не відрізняється від початку з нуля, оскільки новий сертифікат матиме інший підпис, а значить, не перевірятиме існуючі клієнтські серти.
Ремі Бланк

так, ви можете продовжити термін дії ... і менше роботи, ніж відтворити всі pki, клієнтські сертифікати та відновити новий корінь ...
ggrandes

Частина про видачу нових сертифікатів кінцевих організацій не обов'язково відповідає дійсності. Це залежить від того, як представлений ідентифікатор ключа авторитету (AKID) представлений у підлеглих ЦС та сертифікатах кінцевих організацій. Якщо AKID базується на {Розрізненому імені, порядковому номері } , то буде досягнута безперервність. Також див. RFC 4518, Інфраструктура відкритих ключів Internet X.509: Побудова шляху сертифікації .

0

У нас була та сама проблема, і це було в нашому випадку, тому що сервер Debian був застарілий, а у openSSL була ця проблема:

https://en.wikipedia.org/wiki/Year_2038_problem

Остання проблема приносить останню версію OpenSSL, доступну для Debian 6. Усі сертифікати, створені після 23.01.2018, видають Vality: за 1901 рік!

Рішення - оновити OpenSSL. Ви можете знову створити конфігураційні файли (із сертифікатами) для клієнтів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.