Перевірте ланцюжок сертифікатів за допомогою 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.