Проверьте цепочку сертификатов с помощью проверки openssl

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

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

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

Что не так?

Ответ 1

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

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

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

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

Ответ 2

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

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

Update:

Как указывает Грег Сметеллс в комментариях, эта команда неявно доверяет 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: OK

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

Ответ 3

Проблема заключается в том, что openssl -verify не выполняет задания.

Как сказал Прияди, openssl -verify останавливается на первом самоподписанном сертификате, поэтому вы действительно не проверяете цепочку, так как часто промежуточный сертификат самоподписан.

Я предполагаю, что вы хотите быть на 101% уверенным, что файлы сертификата верны, прежде чем пытаться установить их в продуктивной веб-службе. Этот рецепт здесь выполняет именно эту предварительную проверку.

Обратите внимание, что ответ Питера правильный, однако вывод openssl -verify не является ключом к тому, что после этого все действительно работает. Да, это может найти некоторые проблемы, но не все.

Вот script, который выполняет задание, чтобы проверить цепочку сертификатов, прежде чем устанавливать его в 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, который может иметь некоторые обновления

Предпосылки этого script:

  • У вас есть доверенные корневые данные CA в /etc/ssl/certs, как обычно, например, на Ubuntu
  • Создайте каталог DIR, где вы храните 3 файла:
    • DIR/certificate.crt, который содержит сертификат
    • DIR/certificate.key, который содержит секретный ключ для вашего веб-сервиса (без кодовой фразы)
    • DIR/certificate.bundle, который содержит CA-Bundle. О том, как подготовить комплект, см. Ниже.
  • Теперь запустите script: ./check DIR/certificate (предполагается, что script имеет имя check в текущем каталоге)
  • Существует очень маловероятный случай, когда script выводит CA-Bundle is not needed. Это означает, что вы (читаете: /etc/ssl/certs/) уже доверяете сертификату подписи. Но это очень маловероятно в WWW.
  • Для этого тестового порта 4433 необходимо использовать на рабочей станции. И лучше только запустить это в безопасной среде, так как он вскоре откроет порт 4433 для публики, который может видеть внешние подключения во враждебной среде.

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

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

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

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

Са-пакет должен быть составлен в порядке, соответствующем порядку обработки, это означает, что первый необходимый сертификат (промежуточный сертификат, который подписывает ваш сертификат) входит первым в комплект. Затем требуется перекрестная подписка-сертификат.

Обычно ваш ЦС (орган, подписавший ваш сертификат) уже предоставит такой правильный файл ca-bundle. Если нет, вам нужно выбрать все необходимые промежуточные сертификаты и cat их вместе в один файл (в Unix). В Windows вы можете просто открыть текстовый редактор (например, notepad.exe) и вставить сертификаты в файл, сначала нужно сверху и следуйте за другими.

Есть еще одна вещь. Файлы должны быть в формате PEM. Некоторые ЦС выдают DER (двоичный) формат. PEM легко заметить: он читается ASCII. Для mor о том, как преобразовать что-то в PEM, см. Как конвертировать .crt в .pem и следовать по дороге с желтым кирпичом.

Пример:

У вас есть:

  • intermediate2.crt промежуточный сертификат, который подписал ваш certificate.crt
  • intermediate1.crt другой промежуточный сертификат, который поместил intermediate2.crt
  • crossigned.crt, который является сертификатом перекрестной подписи другого CA, который подписал intermediate1.crt
  • crossintermediate.crt, который является другим промежуточным звеном от другого ЦС, который подписал crossigned.crt (вы, вероятно, никогда не увидите такую ​​вещь)

Тогда правильный cat будет выглядеть следующим образом:

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

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

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

Ответ 4

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

Снимок экрана:

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