Перевірте ланцюжок сертифікатів за допомогою openssl verify


128

Я будую власну ланцюжок сертифікатів із такими компонентами:

Root Certificate - Intermediate Certificate - User Certificate

Root Cert - це самопідписаний сертифікат, проміжний сертифікат підписується Root, а користувач - Intermediate.

Тепер я хочу перевірити, чи має Сертифікат користувача прив'язку Root Certificate.

З

openssl verify -verbose -CAfile RootCert.pem Intermediate.pem

перевірка нормально. На наступному кроці я перевіряю User Cert

openssl verify -verbose -CAfile Intermediate.pem UserCert.pem

і підтвердження показує

error 20 at 0 depth lookup:unable to get local issuer certificate

Що не так?

Відповіді:


164

З verifyдокументації:

Якщо знайдено сертифікат, який є його власним емітентом, він вважається кореневим CA.

Іншими словами, root CA повинен підписатися, щоб перевірити, чи працює він. Ось чому ваша друга команда не працювала. Спробуйте це замість цього:

openssl verify -CAfile RootCert.pem -untrusted Intermediate.pem UserCert.pem

Він перевірить всю вашу ланцюжок в одній команді.


2
Я відповідаю голосом за цю відповідь, так як нещодавно мені довелося це зробити, і, спробувавши різні варіанти, перелічені man verify, я виявив, що -untrustedпараметр є правильним, який слід використовувати під час визначення проміжного сертифіката.
— Ентоні Геоґеган

Я думаю, друга відповідь: stackoverflow.com/a/31205833/173062 є більш точною - вона передає ланцюжок сертифікатів до параметра -CAfile.
— Гленджамін

2
-untrustedне перевіряє, чи повноцінна ланцюжок сертифікатів. Будь ласка, врахуйте, щоб передати команду як проміжну, так і root, як -CAfileце підказує інші питання.
— Енвек

2
Використовуйте -надійний для Intermediate.pem, якщо можливо, трапляється таке: mail.python.org/pipermail/cryptography-dev/2016-August/…
— Greg Smethells

2
Про це не вимагало ОП, але у випадку, якщо ви хочете перевірити НЕ підписаний ланцюг, тоді використовуйте файл системи / браузера CA замість власного. Наприклад, на OS X з openssl з домашнього використання:openssl verify -CAfile /usr/local/etc/openssl/cert.pem -untrusted Intermediate.pem UserCert.pem
— Грег Дубіцький

50

Це одне з небагатьох законних робочих місць для cat:

openssl verify -verbose -CAfile <(cat Intermediate.pem RootCert.pem) UserCert.pem

Оновлення:

Як в коментарях зазначає Грег Сметеллс, ця команда неявно довіряє Intermediate.pem . Я рекомендую прочитати першу частину посилань Грега (друга частина спеціально стосується pyOpenSSL і не стосується цього питання).

У разі, якщо повідомлення відійде, я наводжу важливі пункти:

На жаль, "проміжний" серт, який насправді є корінним / самопідписаним, буде розглядатися як довірений СА при використанні рекомендованої команди, наведеної вище:

$ openssl перевірити -CAfile <(cat geotrust_global_ca.pem rogue_ca.pem) fake_sometechcompany_from_rogue_ca.com.pem fake_sometechcompany_from_rogue_ca.com.pem: OK

Здається, що openssl перестане перевіряти ланцюжок, як тільки з’явиться кореневий сертифікат, який також може бути Intermediate.pem, якщо він підписаний самостійно. У цьому випадку RootCert.pem не вважається. Тому переконайтеся, що Intermediate.pem надходить з надійного джерела, перш ніж покластися на команду, що була вище.


Чи справді це буде підтверджувати проміжний cert проти кореневої cert?
— augurar

Це робить. Я просто перезапустив команди ланцюжком, який я знаю, що він правильний (він обслуговує виробничий трафік для мого роботодавця), а потім знову з іншим, не пов'язаним кореневим сертифікатом. Дивіться суть стенограми .
— Пітер

8
ПОПЕРЕДЖЕННЯ: НЕ використовуйте це, якщо Intermediate.pem взагалі не довіряється. Більше інформації читайте тут: mail.python.org/pipermail/cryptography-dev/2016-August/…
— Грег Сметеллс

1
Дякую, що вказали на це, Грег. Коли я дав відповідь, я завантажив корені та проміжні продукти з домашніх сторінок емітентів, тому думка мені не прийшла в голову. Я оновив відповідь, щоб зрозуміти, що проміжному підрозділу невірно довіряють цю команду.
— Пітер

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

17

Проблема в тому, що openssl -verifyце не справляється.

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

Я припускаю, що ви хочете бути впевнені на 101%, що файли сертифікатів є правильними, перш ніж спробувати встановити їх у продуктивній веб-службі. Цей рецепт тут виконує саме цю попередню перевірку.

Зауважте, що відповідь Петра правильна , проте висновок openssl -verifyне має поняття, що все справді працює згодом. Так, це може знайти деякі проблеми, але зовсім не всі.

Ось сценарій, який виконує завдання перевірити ланцюжок сертифікатів, перш ніж встановити його в Apache. Можливо, це можна вдосконалити за допомогою якоїсь більш містичної магії OpenSSL, але я не гуру OpenSSL і наступні роботи:

#!/bin/bash
# This Works is placed under the terms of the Copyright Less License,
# see file COPYRIGHT.CLL.  USE AT OWN RISK, ABSOLUTELY NO WARRANTY. 
#
# COPYRIGHT.CLL can be found at http://permalink.de/tino/cll
# (CLL is CC0 as long as not covered by any Copyright)

OOPS() { echo "OOPS: $*" >&2; exit 23; }

PID=
kick() { [ -n "$PID" ] && kill "$PID" && sleep .2; PID=; }
trap 'kick' 0

serve()
{
kick
PID=
openssl s_server -key "$KEY" -cert "$CRT" "$@" -www &
PID=$!
sleep .5    # give it time to startup
}

check()
{
while read -r line
do
    case "$line" in
    'Verify return code: 0 (ok)')   return 0;;
    'Verify return code: '*)    return 1;;
#   *)  echo "::: $line :::";;
    esac
done < <(echo | openssl s_client -verify 8 -CApath /etc/ssl/certs/)
OOPS "Something failed, verification output not found!"
return 2
}

ARG="${1%.}"
KEY="$ARG.key"
CRT="$ARG.crt"
BND="$ARG.bundle"

for a in "$KEY" "$CRT" "$BND"
do
    [ -s "$a" ] || OOPS "missing $a"
done

serve
check && echo "!!! =========> CA-Bundle is not needed! <========"
echo
serve -CAfile "$BND"
check
ret=$?
kick

echo
case $ret in
0)  echo "EVERYTHING OK"
    echo "SSLCertificateKeyFile $KEY"
    echo "SSLCertificateFile    $CRT"
    echo "SSLCACertificateFile  $BND"
    ;;
*)  echo "!!! =========> something is wrong, verification failed! <======== ($ret)";;
esac

exit $ret

Зауважте, що результат після EVERYTHING OK- це налаштування Apache, тому що люди, які використовують NginXабо, haproxyяк правило, також можуть чудово це читати та розуміти;)

Існує GitHub Gist цього, який може мати деякі оновлення

Передумови цього сценарію:

  • У вас є довірені кореневі дані CA, /etc/ssl/certsяк зазвичай, наприклад, на Ubuntu
  • Створіть каталог, DIRде зберігаються 3 файли:
    • DIR/certificate.crt який містить сертифікат
    • DIR/certificate.key який містить секретний ключ для вашого веб-сервісу (без парольної фрази)
    • DIR/certificate.bundleякий містить пакет CA. Про те, як приготувати заготовку, дивіться нижче.
  • Тепер запустіть скрипт: ./check DIR/certificate(це передбачає, що сценарій названий checkу поточному каталозі)
  • Існує дуже малоймовірний випадок, коли сценарій виводить CA-Bundle is not needed. Це означає, що ви (читайте /etc/ssl/certs/:) вже довіряєте сертифікату підписання. Але це вкрай малоймовірно в WWW.
  • Для цього тестовий порт 4433 повинен бути використаний на вашій робочій станції. І краще лише запустити це в безпечному середовищі, оскільки він відкриє порт 4433 для громадськості, який, можливо, побачить зовнішні з'єднання у ворожій обстановці.

Як створити certificate.bundleфайл?

У WWW ланцюжок довіри зазвичай виглядає так:

  • довірений сертифікат від /etc/ssl/certs
  • невідомі проміжні сертифікати, можливо перехресні підписані іншим ЦА
  • ваш сертифікат ( certificate.crt)

Тепер оцінка проводиться знизу вгору, це означає, що спочатку читається ваш сертифікат, потім потрібен невідомий проміжний сертифікат, потім, можливо, перехресний сертифікат, а потім /etc/ssl/certsпроводиться консультація для пошуку належного довіреного сертифіката.

Пакет ca повинен бути складений у правильному порядку обробки, це означає, що перший необхідний сертифікат (проміжний сертифікат, який підписує ваш сертифікат) надходить спочатку в комплект. Тоді потрібен перехресний підпис.

Зазвичай ваш CA (орган, який підписав ваш сертифікат) вже надасть такий правильний файл ca-bundle. Якщо ні, вам потрібно підібрати всі необхідні проміжні сертифікати та catразом їх в один файл (на Unix). У Windows ви можете просто відкрити текстовий редактор (як notepad.exe) і вставити сертифікати у файл, перший необхідний зверху та наступний за іншими.

Є інша річ. Файли повинні бути у форматі PEM. Деякі ЦА видають формат DER (двійковий). PEM легко помітити: він читається на ASCII. Докладніше про те, як перетворити щось у PEM, див. Як перетворити .crt у .pem та слідувати дорозі жовтої цегли.

Приклад:

Ти маєш:

  • intermediate2.crt проміжний сертифікат, який підписав ваш certificate.crt
  • intermediate1.crt ще один проміжний церт, який співав intermediate2.crt
  • crossigned.crt що є перехресним підписом від іншого ЦА, який підписав intermediate1.crt
  • crossintermediate.crtщо є ще одним посередником від іншого підписаного ЦА crossigned.crt(ви, мабуть, такого ніколи не побачите)

Тоді власне catвиглядатиме так:

cat intermediate2.crt intermediate1.crt crossigned.crt crossintermediate.crt > certificate.bundle

І як можна дізнатися, які файли потрібні чи ні та в якій послідовності?

Ну, експериментуйте, поки checkвам не скажуть, що все в порядку. Це як комп'ютерна гра-головоломка для розгадування загадки. Кожен. Неодружений Час. Навіть для плюсів. Але ви будете ставати кращими щоразу, коли вам це потрібно зробити. Тож ви, безумовно, не самотні з усім цим болем. Це SSL, знаєте? SSL - це, мабуть, одна з найгірших конструкцій, яку я коли-небудь бачив за 30 років професійного адміністрування системи. Ніколи не замислювалися, чому криптовалюта не стала мейнстрімом за останні 30 років? Ось чому. 'Нафф сказав.


Клієнту: Поясніть, будь ласка, що не так у моїй відповіді. Дякую.
— Тіно

2
Я один з низових людей. Що спровокувало зворотний результат, це таке: "І як ви можете дізнатися, які файли потрібні чи ні, і в якій послідовності? Ну, експериментуйте, поки чек не скаже вам, що все в порядку". Я не думаю, що SSL - це особливий випадок. Такі проблеми повинні мати детерміноване рішення.
— ychaouche

2
@ychaouche Дякую! Як ви, мені подобаються детерміновані речі. Питання було "Що не так" і як це зробити за допомогою "openssl verify". Поки ми перебуваємо в потоковому потоці, я пояснив це, після чого слід програмна (таким чином детермінована) відповідь "так / ні". Ви навіть можете використовувати його для автоматизації перевірок на новий комплект, перш ніж встановлювати його у виробництво. Це повністю відповідає на запитання. Що вам не подобається, це те, що я розповів про розчарування на темі "Як створити належний пакет?". Як я вважаю, не може бути короткої детермінованої відповіді на це, відповідь на це буде офтопічним у контексті.
— Тіно

6
"Як згадував Прияді, openssl -перевірка зупиняється на першому самопідписаному сертифікаті, отже, ви не дійсно перевіряєте ланцюг, як часто проміжний сертифікат робиться самопідписаним." Очевидно, проміжні сертифікати ніколи не підписуються (якби вони були кореневими сертифікатами). І вся суть верифікації полягає в тому, щоб перевірити, що ви включили всі сертифікати у ланцюг аж до надійного кореневого сертифіката. Це саме те, що робить перевірка openssl. Однак opensl має тенденцію бути досить консервативним у своїй довірчій політиці ...
— Тимо

4
"часто проміжний сертифікат є самопідписаним". Це неправильно, і термінологічні плутанини, подібні цій, ускладнюють новичкам зрозуміти тему, яка насправді є досить простою, якщо вона пояснюється правильно. З RFC 5280: "[...] Сертифікати ЦС можуть бути додатково розділені на три класи: крос-сертифікати, сертифікати, що видаються самостійно, і сертифікати, що підписуються самостійно. Перехресні сертифікати - це сертифікати ЦС, в яких емітент і суб'єкт є різними суб'єктами Перехресні сертифікати описують довірчі відносини між двома ЦО. [...] ".
— Доктор Ян-Філіп Геркк

8

Мені довелося провести перевірку сертифікату letsencrypt, і я зробив це так:

  1. Завантажте кореневу та середню частину із ланцюга довіри ліценкриптів .
  2. Видайте цю команду:

    $ openssl verify -CAfile letsencrypt-root-cert/isrgrootx1.pem.txt -untrusted letsencrypt-intermediate-cert/letsencryptauthorityx3.pem.txt /etc/letsencrypt/live/sitename.tld/cert.pem 
    /etc/letsencrypt/live/sitename.tld/cert.pem: OK
    

1
Ну, схоже, що Джону це не сподобалось, що я сказала спасибі. Я наполягаю на "Спасибі" жорстко, тому ось видалений текст: Сподіваюсь, він допоможе вам для ваших сертифікатів ліцензорних шифрів. Дякую за Прияді, ваше рішення допомогло мені знайти цю команду. Будь ласка, не забудьте підтримати його рішення.
— Михайло

5

Пробивши цілий день із точно такою самою проблемою, не маючи попередніх знань про сертифікати SSL, я завантажив диспетчер клавіш CERTivity і імпортував до нього свій сховище ключів, і отримав чітку візуалізацію ланцюжка сертифікатів.

Знімок екрана:

введіть тут опис зображення


1
Не намагається відповісти на питання про те, як користуватися openssl verify.
— бінкі

так, але цей інструмент може дати вам необхідну візуалізацію подібних речей, якщо ви не розумієте криптовалютної інформації інструментів командного рядка openssl :) Отже, ось мій підсумок, можливо, є деякі інтернет-речі, які також роблять це.
— Девід 天宇 Вонг

2

Якщо ви хочете , щоб переконатися , що емітент в UserCert.pem дійсності Intermediate.pem зробити наступне (приклад використання: OpenSSL 1.1.1):

openssl verify -no-CAfile -no-CApath -partial_chain -trusted Intermediate.pem UserCert.pem

і ви отримаєте:

UserCert.pem: OK

або

UserCert.pem: verification failed

чи є якась еквівалентна команда для openssl verify -no-CAfile -no-CApath -partial_chain -trusted Intermediate.pem UserCert.pemPython 3.7?
— Богота

-5

Ви можете легко перевірити ланцюжок сертифікатів за допомогою openssl. Повний ланцюг буде включати в себе сертифікат CA, тому ви повинні побачити деталі щодо ЦС та самого сертифіката.

openssl x509 -in fullchain.pem -text -noout


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