Xác minh chuỗi chứng chỉ bằng cách sử dụng openssl xác minh


128

Tôi đang xây dựng một chuỗi chứng chỉ riêng với các thành phần sau:

Root Certificate - Intermediate Certificate - User Certificate

Chứng chỉ gốc là chứng chỉ tự ký, Chứng chỉ trung gian được ký bởi Root và Người dùng bởi Trung cấp.

Bây giờ tôi muốn xác minh xem Chứng chỉ người dùng có neo bằng Chứng chỉ gốc hay không.

Với

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

xác nhận là ok. Trong bước tiếp theo, tôi xác nhận Chứng chỉ người dùng với

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

và xác nhận cho thấy

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

Chuyện gì thế?

Câu trả lời:


164

Từ verifytài liệu:

Nếu một chứng chỉ được tìm thấy là nhà phát hành riêng của nó, nó được coi là CA gốc.

Nói cách khác, CA gốc cần tự ký để xác minh hoạt động. Đây là lý do tại sao lệnh thứ hai của bạn không hoạt động. Hãy thử điều này thay thế:

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

Nó sẽ xác minh toàn bộ chuỗi của bạn trong một lệnh duy nhất.


2
Tôi đang bỏ phiếu cho câu trả lời này vì gần đây tôi phải làm điều này và sau khi thử các tùy chọn khác nhau được liệt kê bởi man verify, tôi thấy rằng -untrustedtham số này là tham số chính xác để sử dụng khi chỉ định chứng chỉ trung gian.
Anthony Geoghegan

Tôi nghĩ rằng câu trả lời thứ hai: stackoverflow.com/a/31205833/173062 chính xác hơn - nó chuyển chuỗi chứng chỉ đến tham số -CAfile.
Glenjamin

2
-untrustedkhông kiểm tra xem chuỗi chứng chỉ có đầy đủ hay không. Vui lòng xem xét để chuyển cả trung gian và gốc để ra lệnh -CAfilenhư các câu hỏi khác cho thấy.
Envek

2
Sử dụng -untrusty cho Middle.pem nếu có thể xảy ra những điều sau đây: mail.python.org/pipermail/cryptography-dev/2016-August/ trộm
Greg Smethells 17/03/2017

2
Đó không phải là những gì OP yêu cầu, nhưng trong trường hợp bạn muốn xác minh chuỗi KHÔNG tự ký, thì hãy sử dụng tệp CA của hệ thống / trình duyệt thay vì của riêng bạn. Ví dụ: trên OS X với openssl từ việc sử dụng homebrew:openssl verify -CAfile /usr/local/etc/openssl/cert.pem -untrusted Intermediate.pem UserCert.pem
Greg Dubicki

50

Đó là một trong số ít các công việc hợp pháp cho cat:

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

Cập nhật:

Như Greg Smethells chỉ ra trong các bình luận, lệnh này hoàn toàn tin tưởng vào Middle.pem . Tôi khuyên bạn nên đọc phần đầu tiên của bài viết tham khảo Greg (phần thứ hai đặc biệt về pyOpenSSL và không liên quan đến câu hỏi này).

Trong trường hợp bài viết biến mất tôi sẽ trích dẫn các đoạn quan trọng:

Thật không may, một chứng chỉ "trung gian" thực sự là một root / tự ký sẽ được coi là một CA đáng tin cậy khi sử dụng lệnh được đề xuất ở trên:

$ openssl xác minh -CAfile <(cat geotrust_global_ca.pem rogue_ca.pem) fake_sometechcompany_from_rogue_ca.com.pem fake_sometechcompany_from_rogue_ca.com.pem: OK

Có vẻ như openssl sẽ ngừng xác minh chuỗi ngay khi gặp chứng chỉ gốc, đây cũng có thể là Trung cấp.pem nếu nó tự ký. Trong trường hợp đó RootCert.pem không được xem xét. Vì vậy, hãy chắc chắn rằng Middle.pem đến từ một nguồn đáng tin cậy trước khi dựa vào lệnh trên.


Điều này sẽ thực sự xác minh chứng chỉ trung gian so với chứng chỉ gốc?
augurar

Nó làm. Tôi chỉ chạy lại các lệnh với một chuỗi mà tôi biết là chính xác (nó phục vụ lưu lượng sản xuất cho chủ nhân của tôi), và sau đó một lần nữa với một chứng chỉ gốc không liên quan. Xem ý chính của bảng điểm .
Peter

8
CẢNH BÁO: KHÔNG sử dụng điều này nếu Middle.pem hoàn toàn không đáng tin cậy. Để biết thêm thông tin, hãy đọc tại đây: mail.python.org/pipermail/cryptography-dev/2016-August/ mẹo
Greg Smethells 17/03/2017

1
Cảm ơn đã chỉ ra rằng, Greg. Khi tôi đưa ra câu trả lời, tôi đã tải xuống cả gốc và trung gian từ trang chủ của nhà phát hành, vì vậy suy nghĩ đã không xảy ra với tôi. Tôi đã cập nhật câu trả lời để làm rõ rằng trung gian được cho là đáng tin cậy với lệnh này.
Peter

1
@somenickname, xem bình luận của Tony. Tùy chọn -untrusty dù sao cũng thích hơn. Tôi đề nghị bạn hỏi câu hỏi của riêng bạn nếu bạn muốn giúp đỡ thêm. Nhận xét không phải là nơi thích hợp để gỡ lỗi vấn đề của bạn.
Peter

17

Vấn đề là, điều openssl -verifyđó không làm được việc.

Như Priyadi đã đề cập , openssl -verifydừng lại ở chứng chỉ tự ký đầu tiên, do đó bạn không thực sự xác minh chuỗi, vì thông thường chứng chỉ trung gian là tự ký.

Tôi giả sử rằng bạn muốn chắc chắn 101%, rằng các tệp chứng chỉ là chính xác trước khi bạn cố gắng cài đặt chúng trong dịch vụ web hiệu quả. Công thức này ở đây thực hiện chính xác kiểm tra trước chuyến bay này.

Xin lưu ý rằng câu trả lời của Peter là chính xác , tuy nhiên đầu ra của openssl -verifykhông có manh mối nào cho thấy mọi thứ thực sự hoạt động sau đó. Vâng, nó có thể tìm thấy một số vấn đề, nhưng không phải tất cả.

Đây là một kịch bản thực hiện công việc xác minh chuỗi chứng chỉ trước khi bạn cài đặt nó vào Apache. Có lẽ điều này có thể được tăng cường với một số phép thuật OpenSSL huyền bí hơn, nhưng tôi không phải là bậc thầy về OpenSSL và các tác phẩm sau:

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

Lưu ý rằng đầu ra sau EVERYTHING OKlà cài đặt Apache, bởi vì mọi người sử dụng NginXhoặc haproxythường có thể đọc và hiểu điều này một cách hoàn hảo;)

Có một GitHub Gist về điều này có thể có một số cập nhật

Điều kiện tiên quyết của kịch bản này:

  • Bạn có dữ liệu gốc CA đáng tin cậy /etc/ssl/certsnhư bình thường, ví dụ như trên Ubuntu
  • Tạo một thư mục DIRnơi bạn lưu trữ 3 tệp:
    • DIR/certificate.crt trong đó có chứng chỉ
    • DIR/certificate.key có chứa khóa bí mật cho dịch vụ web của bạn (không có cụm mật khẩu)
    • DIR/certificate.bundletrong đó có gói CA-Bundle. Về cách chuẩn bị bó, xem bên dưới.
  • Bây giờ hãy chạy tập lệnh: ./check DIR/certificate(điều này giả sử rằng tập lệnh được đặt tên checktrong thư mục hiện tại)
  • Có một trường hợp rất khó xảy ra là kịch bản đầu ra CA-Bundle is not needed. Điều này có nghĩa là bạn (đọc /etc/ssl/certs/:) đã tin tưởng vào chứng chỉ ký. Nhưng điều này rất khó xảy ra trong WWW.
  • Đối với cổng kiểm tra này, 4433 phải không được sử dụng trên máy trạm của bạn. Và tốt hơn là chỉ chạy cái này trong một môi trường an toàn, vì nó sẽ mở cổng 4433 cho công chúng, điều này có thể thấy các kết nối nước ngoài trong một môi trường thù địch.

Làm thế nào để tạo certificate.bundletập tin?

Trong WWW, chuỗi tin cậy thường trông như thế này:

  • chứng chỉ tin cậy từ /etc/ssl/certs
  • (các) chứng chỉ trung gian không xác định, có thể được ký bởi CA khác
  • chứng chỉ của bạn ( certificate.crt)

Bây giờ, việc đánh giá diễn ra từ dưới lên trên, điều này có nghĩa là, đầu tiên, chứng chỉ của bạn được đọc, sau đó là chứng chỉ trung gian không xác định, sau đó có lẽ là chứng chỉ ký chéo và sau đó /etc/ssl/certsđược tư vấn để tìm chứng chỉ tin cậy phù hợp.

Gói ca phải được tạo thành chính xác theo thứ tự xử lý đúng, điều này có nghĩa là chứng chỉ cần thiết đầu tiên (chứng chỉ trung gian ký chứng chỉ của bạn) xuất hiện đầu tiên trong gói. Sau đó, chứng nhận chữ ký chéo là cần thiết.

Thông thường CA của bạn (cơ quan đã ký chứng chỉ của bạn) sẽ cung cấp một tệp ca-bundle thích hợp như vậy. Nếu không, bạn cần chọn tất cả các chứng chỉ trung gian cần thiết và catchúng cùng nhau thành một tệp duy nhất (trên Unix). Trên Windows, bạn có thể chỉ cần mở trình soạn thảo văn bản (như notepad.exe) và dán chứng chỉ vào tệp, cái đầu tiên cần thiết ở trên và theo sau những cái khác.

Có một điều khác. Các tập tin cần phải ở định dạng PEM. Một số CA phát hành định dạng DER (nhị phân). PEM rất dễ nhận ra: Nó có thể đọc được ASCII. Để biết cách chuyển đổi một cái gì đó thành PEM, hãy xem Cách chuyển đổi .crt sang .pem và đi theo con đường gạch màu vàng.

Thí dụ:

Bạn có:

  • intermediate2.crt chứng chỉ trung gian đã ký certificate.crt
  • intermediate1.crt một chứng chỉ trung gian khác, được hát intermediate2.crt
  • crossigned.crt đó là một chứng chỉ ký chéo từ một CA khác, đã ký intermediate1.crt
  • crossintermediate.crtđó là một trung gian khác từ CA khác đã ký crossigned.crt(có thể bạn sẽ không bao giờ thấy điều đó)

Sau đó, sự phù hợp catsẽ như thế này:

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

Và làm thế nào bạn có thể tìm ra những tập tin nào là cần thiết hay không và theo trình tự nào?

Vâng, thử nghiệm, cho đến khi checkcho bạn biết tất cả mọi thứ là OK. Nó giống như một trò chơi giải đố trên máy tính để giải câu đố. Mỗi. Độc thân. Thời gian. Ngay cả cho thuận. Nhưng bạn sẽ trở nên tốt hơn mỗi khi bạn cần làm điều này. Vì vậy, bạn chắc chắn không cô đơn với tất cả nỗi đau đó. Đó là SSL, bạn biết không? SSL có lẽ là một trong những thiết kế tồi tệ nhất tôi từng thấy trong hơn 30 năm quản trị hệ thống chuyên nghiệp. Bạn có bao giờ tự hỏi tại sao tiền điện tử không trở thành xu hướng trong 30 năm qua không? Đó là lý do tại sao. 'nuff nói.


Gửi người xuống: Hãy giải thích những gì sai với câu trả lời của tôi. Cảm ơn.
Tino

2
Tôi là một trong những người downvoters. Điều kích hoạt downvote là thế này: "Và làm thế nào bạn có thể tìm ra tập tin nào cần thiết hay không và theo trình tự nào? Vâng, thử nghiệm, cho đến khi kiểm tra cho bạn biết mọi thứ đều ổn". Tôi không nghĩ SSL là một trường hợp đặc biệt. Các vấn đề như thế này nên có một giải pháp xác định.
ychaouche

2
@ychaouche Cảm ơn! Giống như bạn, tôi thích những thứ vô định. Câu hỏi là "Cái gì sai" và cách thực hiện với "openssl verify". Khi chúng tôi đang ở trên stackoverflow, tôi đã giải thích rằng, theo sau là một câu trả lời có lập trình (do đó mang tính quyết định) có / không. Bạn thậm chí có thể sử dụng nó để tự động kiểm tra Bundle mới trước khi cài đặt nó vào sản xuất. Điều này trả lời đầy đủ câu hỏi. Điều bạn không thích là tôi đã nói về sự thất vọng về "Làm thế nào để tạo ra một gói phù hợp?". Theo tôi nghĩ không thể có một câu trả lời xác định ngắn cho điều đó, trả lời điều này sẽ là không chính đáng trong bối cảnh ở đây.
Tino

6
"Như Priyadi đã đề cập, openssl - xác minh dừng tại chứng chỉ tự ký đầu tiên, do đó bạn không thực sự xác minh chuỗi, vì thông thường chứng chỉ trung gian là tự ký." Rõ ràng chứng chỉ trung gian không bao giờ tự ký (nếu chúng là chứng chỉ gốc). Và toàn bộ điểm xác minh là kiểm tra xem bạn đã bao gồm tất cả các chứng chỉ trong chuỗi cho đến chứng chỉ gốc đáng tin cậy chưa. Đây chính xác là những gì xác thực openssl làm. Tuy nhiên, openssl có xu hướng khá bảo thủ với các chính sách đáng tin cậy của nó ...
Timo

4
"Thường thì chứng chỉ trung gian là tự ký". Điều này là sai, và những nhầm lẫn thuật ngữ như thế này khiến người mới khó hiểu được một chủ đề thực sự khá đơn giản khi được giải thích đúng cách. Từ RFC 5280: "[...] Chứng chỉ CA có thể được chia thành ba loại: chứng chỉ chéo, chứng chỉ tự cấp và chứng chỉ tự ký. Chứng chỉ chéo là chứng chỉ CA trong đó tổ chức phát hành và chủ thể là các thực thể khác nhau Giấy chứng nhận chéo mô tả mối quan hệ tin cậy giữa hai CA. [...] ".
Tiến sĩ Jan-Philip Gehrcke

8

Tôi đã phải xác minh chứng chỉ letencrypt và tôi đã làm như thế này:

  1. Tải xuống chứng chỉ gốc và chứng chỉ trung gian từ chuỗi tin cậy letencrypt .
  2. Ban hành lệnh này:

    $ 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
Chà, có vẻ như John không thích nó mà tôi nói cảm ơn. Tôi nhấn mạnh vào "Cảm ơn" khó khăn, vì vậy đây là văn bản đã bị xóa: Hy vọng nó sẽ giúp bạn cho các phần mềm letencrypt của bạn. Cảm ơn Priyadi, giải pháp của bạn đã giúp tôi tìm ra lệnh này. Hãy chắc chắn để nâng cao giải pháp của mình.
Michael

5

Sau khi phá vỡ cả ngày về cùng một vấn đề, không có kiến ​​thức trước về chứng chỉ SSL, tôi đã tải xuống Trình quản lý kho khóa CERTivity và nhập kho khóa của tôi vào đó và có được hình dung rõ ràng về chuỗi chứng chỉ.

Ảnh chụp màn hình:

nhập mô tả hình ảnh ở đây


1
Không cố gắng trả lời câu hỏi về cách sử dụng openssl verify.
binki

đúng nhưng loại công cụ này có thể cung cấp cho bạn hình dung cần thiết về những thứ đó nếu bạn không hiểu thông tin khó hiểu của các công cụ dòng lệnh openssl :) Vì vậy, đây là upvote của tôi, có thể có một số công cụ trực tuyến cũng làm điều đó.
David Wong

2

Nếu bạn chỉ muốn xác minh rằng tổ chức phát hành của UserCert.pem là thực sự Intermediate.pem làm như sau (sử dụng ví dụ: OpenSSL 1.1.1):

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

và bạn sẽ nhận được:

UserCert.pem: OK

hoặc là

UserCert.pem: verification failed

Có lệnh tương đương nào openssl verify -no-CAfile -no-CApath -partial_chain -trusted Intermediate.pem UserCert.pemtrong Python 3.7 không?
Bogota

-5

Bạn có thể dễ dàng xác minh chuỗi chứng chỉ với openssl. Fullchain sẽ bao gồm chứng chỉ CA, do đó bạn sẽ thấy chi tiết về CA và chính chứng chỉ đó.

openssl x509 -in fullchain.pem -text -không


4
1) Điều này là hoàn toàn không có bất kỳ loại giải thích. 2) đây là câu trả lời cho câu hỏi mà người hỏi không hỏi, không có bất kỳ bối cảnh nào.
Shadur
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.