it-roy-ru.com

Проверьте цепочку сертификатов, используя openssl verify

Я строю собственную цепочку сертификатов со следующими компонентами:
Root Certificate - Intermediate Certificate - User Certificate
Root Cert является самозаверяющим сертификатом, промежуточный сертификат подписывается Root и пользователем - Intermediate.

Теперь я хочу проверить, привязан ли сертификат пользователя к корневому сертификату.

С
openssl verify -verbose -CAfile RootCert.pem Intermediate.pem
проверка в порядке. На следующем шаге я проверяю пользовательский сертификат с помощью
openssl verify -verbose -CAfile Intermediate.pem UserCert.pem
и проверка показывает ошибку 20 при поиске глубины 0: невозможно получить сертификат локального эмитента

Что случилось?

101
Indra

Из документации 'verify': "Если найден сертификат, который является его собственным эмитентом, он считается корневым CA". Другими словами, для проверки работоспособности корневому центру сертификации необходимо самостоятельно подписаться. Вот почему ваша вторая команда не сработала.

Попробуйте это вместо:

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

Он проверит всю вашу цепочку в одной команде.

119
Priyadi

Это одна из немногих законных работ для cat:

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

Обновление:

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

Если сообщение исчезнет, ​​я процитирую важные параграфы:

К сожалению, "промежуточный" сертификат, который на самом деле является корневым/самозаверяющим , будет считаться доверенным центром сертификации при использовании рекомендованной команды, приведенной выше:

$ openssl verify -CAfile <(cat geotrust_global_ca.pem rogue_ca.pem) fake_sometechcompany_from_rogue_ca.com.pem fake_sometechcompany_from_rogue_ca.com.pem: ОК

Кажется, openssl прекратит проверку цепочки, как только будет обнаружен корневой сертификат, который также может быть Intermediate.pem, если он самоподписан. В этом случае RootCert.pem не рассматривается. Поэтому убедитесь, что Intermediate.pem исходит из доверенного источника, прежде чем полагаться на команду, приведенную выше.

39
Peter

Проблема в том, что openssl -verify не выполняет эту работу.

Как упомянул Priyadi , 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" "[email protected]" -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-Bundle. О том, как подготовить комплект, смотрите ниже.
  • Теперь запустите скрипт: ./check DIR/certificate (предполагается, что скрипт называется check в текущем каталоге)
  • Очень маловероятно, что скрипт выдаст CA-Bundle is not needed. Это означает, что вы (читай: /etc/ssl/certs/) уже доверяете подписывающему сертификату. Но это очень маловероятно в WWW.
  • Для этого теста порт 4433 должен быть не использован на вашей рабочей станции. И лучше запускать это только в безопасной среде, так как вскоре он открывает порт 4433 для публики, которая может видеть внешние соединения в агрессивной среде.

Как создать файл certificate.bundle?

В WWW цепочка доверия обычно выглядит так:

  • доверенный сертификат от /etc/ssl/certs
  • неизвестные промежуточные сертификаты, возможно, перекрестно подписанные другим CA
  • ваш сертификат (certificate.crt)

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

Пакет должен быть составлен в точно правильном порядке обработки, это означает, что первый необходимый сертификат (промежуточный сертификат, который подписывает ваш сертификат) стоит первым в пакете. Тогда необходима перекрестная подпись.

Обычно ваш 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, который является сертификатом перекрестной подписи от другого CA, который подписал intermediate1.crt
  • crossintermediate.crt, который является другим промежуточным звеном от другого CA, который подписал crossigned.crt (вы, вероятно, никогда не увидите такую ​​вещь)

Тогда правильное cat будет выглядеть так:

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

А как узнать какие файлы нужны или нет и в какой последовательности?

Ну, экспериментируйте, пока check не скажет вам, что все в порядке. Это похоже на компьютерную головоломку, чтобы разгадать загадку. Каждый. Не замужем. Время. Даже для профи. Но вы будете поправляться каждый раз, когда вам нужно будет это сделать. Так что вы определенно не одиноки со всей этой болью. Это SSL, понимаешь? SSL, вероятно, один из худших проектов, которые я когда-либо видел за более чем 30 лет профессионального системного администрирования. Вы когда-нибудь задумывались, почему криптография не стала мейнстримом за последние 30 лет? Вот почему. 'достаточно.

12
Tino

Я должен был сделать проверку сертификата letsencrypt, и я сделал это так:

  1. Загрузите корневой сертификат и промежуточный сертификат из цепочки доверия letsencrypt: https://letsencrypt.org/certificates/
  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

Надеюсь, это поможет вам для ваших сертификатов letsencrypt Спасибо за Priyadi, ваше решение помогло мне найти эту команду. Palease убедитесь, что проголосовали за его решение.

5
Michael

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

Скриншот :

enter image description here

3
praveen.chandran