Verifikasi rantai sertifikat menggunakan openssl memverifikasi

128

Saya sedang membangun rantai sertifikat sendiri dengan komponen berikut:

Root Certificate - Intermediate Certificate - User Certificate

Root Cert adalah sertifikat yang ditandatangani sendiri, Sertifikat Menengah ditandatangani oleh Root dan Pengguna oleh Menengah.

Sekarang saya ingin memverifikasi apakah Sertifikat Pengguna memiliki jangkar oleh Root Certificate.

Dengan

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

validasinya ok. Pada langkah berikutnya saya memvalidasi Sertifikat Pengguna dengan

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

dan validasi menunjukkan

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

Apa yang salah?

Indera
sumber

Jawaban:

164

Dari verifydokumentasi:

Jika suatu sertifikat ditemukan yang merupakan penerbitnya sendiri, ia dianggap sebagai root CA.

Dengan kata lain, root CA perlu ditandatangani sendiri untuk verifikasi agar berfungsi. Inilah sebabnya mengapa perintah kedua Anda tidak berhasil. Coba ini sebagai gantinya:

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

Ini akan memverifikasi seluruh rantai Anda dalam satu perintah.

Priyadi
sumber
2
Saya memilih-up jawaban ini karena saya baru-baru ini harus melakukan ini dan setelah mencoba opsi yang berbeda terdaftar oleh man verify, saya menemukan bahwa -untrustedparameter adalah yang benar untuk digunakan ketika menentukan sertifikat perantara.
Anthony Geoghegan
Saya pikir jawaban kedua: stackoverflow.com/a/31205833/173062 lebih akurat - melewati rantai sertifikat ke parameter -CAfile.
Glenjamin
2
-untrustedtidak memeriksa apakah rantai sertifikat sepenuhnya valid. Harap pertimbangkan untuk meneruskan perintah perantara dan root ke perintah seperti yang -CAfiledisarankan pertanyaan lain.
Envek
2
Gunakan -untrusted untuk Intermediate.pem jika ada kemungkinan hal berikut terjadi: mail.python.org/pipermail/cryptography-dev/2016-August/…
Greg Smethells
2
Bukan itu yang diminta OP, tetapi jika Anda ingin memverifikasi BUKAN rantai yang ditandatangani sendiri, maka gunakan file CA sistem / browser alih-alih milik Anda. Misalnya pada OS X dengan openssl dari penggunaan homebrew:openssl verify -CAfile /usr/local/etc/openssl/cert.pem -untrusted Intermediate.pem UserCert.pem
Greg Dubicki
50

Itulah salah satu dari sedikit pekerjaan yang sah untuk cat:

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

Memperbarui:

Seperti yang ditunjukkan Greg Smethells dalam komentar, perintah ini secara implisit mempercayai Intermediate.pem . Saya sarankan membaca bagian pertama dari posting referensi Greg (bagian kedua secara khusus tentang pyOpenSSL dan tidak relevan dengan pertanyaan ini).

Jika posting hilang, saya akan mengutip paragraf penting:

Sayangnya, sertifikat "perantara" yang sebenarnya merupakan root / yang ditandatangani sendiri akan diperlakukan sebagai CA tepercaya saat menggunakan perintah yang disarankan di atas:

$ openssl memverifikasi -CAfile <(cat geotrust_global_ca.pem rogue_ca.pem) fake_sometechcompany_from_rogue_ca.com.pem fake_sometechcompany_from_rogue_ca.com.pem: OK

Tampaknya openssl akan berhenti memverifikasi rantai segera setelah sertifikat root ditemukan, yang mungkin juga Intermediate.pem jika ditandatangani sendiri. Dalam hal ini RootCert.pem tidak dipertimbangkan. Jadi pastikan Intermediate.pem berasal dari sumber yang tepercaya sebelum mengandalkan perintah di atas.

Peter
sumber
Apakah ini benar-benar memverifikasi sertifikat perantara terhadap sertifikat root?
augurar
Itu benar. Saya hanya menjalankan ulang perintah dengan rantai yang saya tahu benar (melayani lalu lintas produksi untuk majikan saya), dan sekali lagi dengan sertifikat root lain yang tidak terkait. Lihat inti transkripnya .
Peter
8
PERINGATAN: JANGAN gunakan ini jika Intermediate.pem sama sekali tidak dipercaya. Untuk info lebih lanjut baca di sini: mail.python.org/pipermail/cryptography-dev/2016-August/…
Greg Smethells
1
Terima kasih telah menunjukkannya, Greg. Ketika saya memberikan jawaban, saya mengunduh akar dan perantara dari beranda penerbit, sehingga pikiran itu tidak terpikir oleh saya. Saya telah memperbarui jawaban untuk memperjelas bahwa perantara tersebut secara implisit dipercaya dengan perintah ini.
Peter
1
@somenickname, lihat komentar Tony. Opsi -percayaan lebih disukai pula. Saya sarankan Anda mengajukan pertanyaan Anda sendiri jika Anda ingin bantuan lebih lanjut. Komentar bukanlah tempat yang tepat untuk men-debug masalah Anda.
Peter
17

Masalahnya adalah, itu openssl -verifytidak melakukan pekerjaan.

Seperti yang disebutkan Priyadi , openssl -verifyberhenti pada sertifikat yang ditandatangani sendiri pertama, maka Anda tidak benar-benar memverifikasi rantai, karena seringkali sertifikat perantara ditandatangani sendiri.

Saya berasumsi bahwa Anda ingin 101% yakin, bahwa file sertifikat sudah benar sebelum Anda mencoba menginstalnya di layanan web produktif. Resep ini di sini melakukan persis seperti pra-penerbangan-cek ini.

Harap dicatat bahwa jawaban Peter benar , namun hasil dari openssl -verifytidak ada petunjuk bahwa semuanya benar-benar berfungsi sesudahnya. Ya, mungkin menemukan beberapa masalah, tetapi tidak semua.

Berikut ini adalah skrip yang melakukan pekerjaan untuk memverifikasi rantai sertifikat sebelum Anda menginstalnya ke dalam Apache. Mungkin ini dapat ditingkatkan dengan beberapa keajaiban OpenSSL yang lebih mistik, tetapi saya bukan guru OpenSSL dan karya-karya berikut:

#!/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

Perhatikan bahwa output setelahnya EVERYTHING OKadalah pengaturan Apache, karena orang yang menggunakan NginXatau haproxybiasanya dapat membaca dan memahami ini juga;)

Ada GitHub Gist ini yang mungkin memiliki beberapa pembaruan

Prasyarat skrip ini:

  • Anda memiliki data root CA tepercaya /etc/ssl/certsseperti biasa misalnya di Ubuntu
  • Buat direktori DIRtempat Anda menyimpan 3 file:
    • DIR/certificate.crt yang berisi sertifikat
    • DIR/certificate.key yang berisi kunci rahasia untuk layanan web Anda (tanpa frasa sandi)
    • DIR/certificate.bundleyang berisi CA-Bundle. Tentang cara menyiapkan bundel, lihat di bawah.
  • Sekarang jalankan skrip: ./check DIR/certificate(ini mengasumsikan bahwa skrip dinamai checkdalam direktori saat ini)
  • Ada kasus yang sangat tidak mungkin yang dihasilkan skrip CA-Bundle is not needed. Ini berarti bahwa Anda (baca /etc/ssl/certs/:) sudah mempercayai sertifikat penandatanganan. Tapi ini sangat tidak mungkin di WWW.
  • Untuk port tes ini, 4433 harus tidak digunakan di workstation Anda. Dan lebih baik hanya menjalankan ini di lingkungan yang aman, karena membuka port 4433 segera ke publik, yang mungkin melihat orang asing terhubung dalam lingkungan yang bermusuhan.

Bagaimana cara membuat certificate.bundlefile?

Di WWW rantai kepercayaan biasanya terlihat seperti ini:

  • sertifikat tepercaya dari /etc/ssl/certs
  • sertifikat perantara tidak dikenal, mungkin ditandatangani oleh CA lain
  • sertifikat Anda ( certificate.crt)

Sekarang, evaluasi berlangsung dari bawah ke atas, ini berarti, pertama, sertifikat Anda dibaca, maka sertifikat perantara yang tidak diketahui diperlukan, kemudian mungkin sertifikat penandatanganan silang dan kemudian /etc/ssl/certsdikonsultasikan untuk menemukan sertifikat tepercaya yang tepat.

Bundel harus dibuat dalam urutan pemrosesan yang tepat, ini berarti, sertifikat yang diperlukan pertama (sertifikat perantara yang menandatangani sertifikat Anda) datang terlebih dahulu dalam bundel. Maka lintas-penandatanganan sertifikat diperlukan.

Biasanya CA Anda (otoritas yang menandatangani sertifikat Anda) akan sudah menyediakan file ca-bundle yang tepat. Jika tidak, Anda harus memilih semua sertifikat perantara yang diperlukan dan catsemuanya menjadi satu file (pada Unix). Di Windows, Anda cukup membuka editor teks (seperti notepad.exe) dan menempelkan sertifikat ke dalam file, yang pertama diperlukan di atas dan mengikuti yang lain.

Ada satu hal lagi. File harus dalam format PEM. Beberapa CA mengeluarkan format DER (biner). PEM mudah dikenali: ASCII dapat dibaca. Untuk lebih lanjut tentang cara mengubah sesuatu menjadi PEM, lihat Cara mengkonversi .crt ke .pem dan ikuti jalan bata kuning.

Contoh:

Kamu punya:

  • intermediate2.crt sertifikat lanjutan yang menandatangani certificate.crt
  • intermediate1.crt sertifikat perantara lain, yang dinyanyikan intermediate2.crt
  • crossigned.crt yang merupakan sertifikat penandatanganan silang dari CA lain, yang ditandatangani intermediate1.crt
  • crossintermediate.crtyang merupakan perantara lain dari CA lain yang menandatangani crossigned.crt(Anda mungkin tidak akan pernah melihat hal seperti itu)

Maka yang tepat catakan terlihat seperti ini:

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

Dan bagaimana Anda bisa mengetahui file mana yang dibutuhkan atau tidak dan dalam urutan apa?

Nah, bereksperimen, sampai checkmemberitahu Anda semuanya baik-baik saja. Ini seperti permainan puzzle komputer untuk memecahkan teka-teki itu. Setiap. Tunggal. Waktu. Bahkan untuk pro. Tetapi Anda akan menjadi lebih baik setiap kali Anda perlu melakukan ini. Jadi, Anda pasti tidak sendirian dengan semua rasa sakit itu. Ini SSL, Anda tahu? SSL mungkin adalah salah satu desain terburuk yang pernah saya lihat dalam lebih dari 30 tahun administrasi sistem profesional. Pernah bertanya-tanya mengapa crypto belum menjadi arus utama dalam 30 tahun terakhir? Itu sebabnya. kata Nuff.

Tino
sumber
Kepada para downvoter: Tolong jelaskan apa yang salah dengan jawaban saya. Terima kasih.
Tino
2
Saya adalah salah satu downvoters. Apa yang memicu downvote adalah ini: "Dan bagaimana Anda bisa mengetahui file mana yang dibutuhkan atau tidak dan dalam urutan yang mana? Nah, bereksperimen, sampai cek memberi tahu Anda semuanya baik-baik saja". Saya tidak berpikir SSL adalah kasus khusus. Masalah seperti ini harus memiliki solusi deterministik.
ychaouche
2
@ychaouche Terima kasih! Seperti kamu, aku suka hal-hal yang merusak. Pertanyaannya adalah, "Apa yang salah" dan bagaimana melakukannya dengan "openssl memverifikasi". Ketika kita berada di stackoverflow, saya menjelaskan bahwa, diikuti oleh jawaban terprogram (dengan demikian deterministik) ya / tidak. Anda bahkan dapat menggunakannya untuk mengotomatiskan cek untuk Bundel baru sebelum memasangnya ke dalam produksi. Ini sepenuhnya menjawab pertanyaan. Yang tidak Anda sukai adalah saya memberi tahu tentang frustrasi pada "Cara membuat bundel yang tepat?". Karena saya pikir tidak akan ada jawaban deterministik singkat untuk itu, menjawab ini akan menjadi offtopic dalam konteks di sini.
Tino
6
"Seperti yang dikatakan Priyadi, opensl -verify stops pada sertifikat yang ditandatangani sendiri pertama, maka Anda tidak benar-benar memverifikasi rantai, karena seringkali sertifikat perantara ditandatangani sendiri." Jelas sertifikat menengah tidak pernah ditandatangani sendiri (jika mereka akan menjadi sertifikat root). Dan seluruh poin verifikasi adalah untuk memeriksa bahwa Anda telah memasukkan semua sertifikat dalam rantai sampai ke sertifikat akar tepercaya. Inilah yang dilakukan oleh openssl memverifikasi. Namun, openssl cenderung agak konservatif dengan kebijakan yang dapat dipercaya ...
Timo
4
"Seringkali sertifikat perantara ditandatangani sendiri". Ini salah, dan kebingungan terminologi seperti ini membuat sulit bagi pendatang baru untuk memahami topik yang sebenarnya agak sederhana ketika dijelaskan dengan cara yang benar. Dari RFC 5280: "[...] Sertifikat CA dapat dibagi lagi menjadi tiga kelas: sertifikat silang, sertifikat yang diterbitkan sendiri, dan sertifikat yang ditandatangani sendiri. Sertifikat silang adalah sertifikat CA di mana penerbit dan subjek adalah entitas yang berbeda Sertifikat silang menggambarkan hubungan saling percaya antara kedua CA. [...] ".
Dr. Jan-Philip Gehrcke
8

Saya harus melakukan verifikasi sertifikat allowencrypt dan saya melakukannya seperti ini:

  1. Unduh sertifikat root dan sertifikat menengah dari rantai kepercayaan allowencrypt .
  2. Terbitkan perintah ini:

    $ 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
    
Michael
sumber
1
Yah, sepertinya John tidak suka kalau aku bilang terima kasih. Saya bersikeras keras "Terima Kasih", jadi inilah teks yang dihapus: Semoga ini membantu Anda untuk sertifikat enkripsi Anda. Terima kasih untuk Priyadi, solusi Anda membantu saya menemukan perintah ini. Pastikan untuk mengunggah solusinya.
Michael
5

Setelah menghabiskan satu hari penuh pada masalah yang sama persis, tanpa pengetahuan sebelumnya tentang sertifikat SSL, saya mengunduh CERTivity Keystores Manager dan mengimpor keystore saya ke sana, dan mendapatkan visualisasi yang jelas dari rantai sertifikat.

Tangkapan layar:

masukkan deskripsi gambar di sini

praveen.chandran
sumber
1
Tidak mencoba menjawab pertanyaan tentang cara menggunakan openssl verify.
binki
ya tetapi alat semacam ini dapat memberi Anda visualisasi yang diperlukan dari hal-hal semacam itu jika Anda tidak memahami informasi samar alat baris perintah openssl :) Jadi inilah upvote saya, mungkin ada beberapa hal online yang melakukan hal itu juga.
David 天宇 Wong
2

Jika Anda hanya ingin memastikan bahwa penerbit dari UserCert.pem sebenarnya Intermediate.pem melakukan hal berikut (contoh penggunaan: OpenSSL 1.1.1):

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

dan Anda akan mendapatkan:

UserCert.pem: OK

atau

UserCert.pem: verification failed
Marinos An
sumber
apakah ada perintah yang setara untuk openssl verify -no-CAfile -no-CApath -partial_chain -trusted Intermediate.pem UserCert.pemdi Python 3.7?
Bogota
-5

Anda dapat dengan mudah memverifikasi rantai sertifikat dengan openssl. Fullchain akan menyertakan sertifikat CA sehingga Anda harus melihat detail tentang CA dan sertifikat itu sendiri.

openssl x509 -di fullchain.pem -teks -tidak

jorfus
sumber
4
1) Ini sepenuhnya tanpa penjelasan apa pun. 2) ini adalah jawaban untuk pertanyaan yang tidak diajukan penanya, tanpa konteks apa pun.
Shadur