如何验证ECDSA和RSA证书

时间:2016-06-22 02:02:23

标签: bash ssl openssl certificate lets-encrypt

我将在中央网络服务器上运行acme-tiny,以便获得我发布的两个Nginx反向代理的证书。新创建的证书通过https发布,可通过下载提供给反向代理。

我希望Nginx服务器在将旧证书替换为新证书之前检查新创建的证书。为此,我编写了以下bash脚本,它在每个Nginx服务器上运行。我想知道我是否错过了什么,或者你是否有改进的想法。或者有更好的方法来实现这个目标吗?

#!/bin/bash

set -e

# Commands for deriving the public keys:
# openssl ec  -in ecdsa.key -pubout > ecdsa_public_key.pem
# openssl rsa -in rsa.key   -pubout > rsa_public_key.pem

curl -O https://example.org/ecdsa.pem
curl -O https://example.org/intermediate.pem
curl -O https://example.org/rsa.pem

# Are the certificates not expired?
# Have they (ecdsa.pem, rsa.pem) been recently issued (validity >= 80 days)?
openssl x509 -checkend 6912000 -noout -in intermediate.pem
openssl x509 -checkend 6912000 -noout -in ecdsa.pem
openssl x509 -checkend 6912000 -noout -in rsa.pem

# Do the private keys and certificates belong together?
openssl x509 -in ecdsa.pem -pubkey | \
   sed -n '/-----BEGIN PUBLIC KEY-----/,/-----END PUBLIC KEY-----/p' | \
   cmp - ecdsa_public_key.pem
openssl x509 -in rsa.pem   -pubkey | \
   sed -n '/-----BEGIN PUBLIC KEY-----/,/-----END PUBLIC KEY-----/p' | \
   cmp - rsa_public_key.pem

# Is the certificate chain valid?
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt intermediate.pem
openssl verify -CAfile intermediate.pem ecdsa.pem
openssl verify -CAfile intermediate.pem rsa.pem

# Are the certificates issued for the correct domain names?
(openssl x509 -noout -subject -in ecdsa.pem | awk -F'CN=' '{print $2}' | \
   awk -F'/' '{print $1}'; \
   openssl x509 -noout -text -in ecdsa.pem | grep "^[[:space:]]*DNS:" | \
   xargs | tr ' ' '\n' | grep ^DNS | sed 's/^DNS://' | sed 's/,$//')| \
   sort | uniq | cmp - domains.txt
(openssl x509 -noout -subject -in rsa.pem   | awk -F'CN=' '{print $2}' | \
   awk -F'/' '{print $1}'; \
   openssl x509 -noout -text -in rsa.pem   | grep "^[[:space:]]*DNS:" | \
   xargs | tr ' ' '\n' | grep ^DNS | sed 's/^DNS://' | sed 's/,$//')| \
   sort | uniq | cmp - domains.txt

更新1:

正如我所说,我想检查证书的每个方面,而不仅仅是证书链的有效性。它目前检查:

  • 链的有效性,
  • 私钥和证书是否匹配,
  • 最近颁发的证书是否已取代旧版证书
  • 是否已针对所需域名颁发证书

因此,它与链接的问题不重复。并且,我想知道我是否忘记了一些检查或是否有改进的空间。以下是对bash脚本的更新。当心我还没有彻底测试过它。

#!/bin/bash
set -e

# Execute the script:
# ( cd /path_to_workdir && \
#   su - james -c "./check_cert.sh https://www.example.org intermediate.pem ecdsa.pem ecdsa_pubkey.pem /etc/ssl/certs/ca-certificates.crt domains.txt pass.txt" && \
#   su - james -c "./check_cert.sh https://www.example.org intermediate.pem rsa.pem rsa_pubkey.pem /etc/ssl/certs/ca-certificates.crt domains.txt pass.txt" && \
#   cat ecdsa.pem intermediate.pem > /etc/nginx/ssl/ecdsa_bundle.pem ) && \
#   cat rsa.pem intermediate.pem > /etc/nginx/ssl/rsa_bundle.pem ) && \
# /etc/init.d/nginx reload

# Download URL, e.g. https://example.org
URL=$1

# Intermediate certificate of certificate chain
INTERMEDIATE=$2

# Issued certificate, e.g. ecdsa.pem
CERT=$3 

# Public key derived from private key via:
# openssl ec  -in ecdsa.key -pubout > ecdsa_pubkey.pem
# openssl rsa -in rsa.key   -pubout > rsa_pubkey.pem
PUBKEY=$4

# ca-certificates file, e.g. /etc/ssl/certs/ca-certificates.crt
CACERTS=$5

# Domains that the cert should cover
DOMAINS=$6

# password-file.txt possible content:
# machine example.org login james password H3Llo
PASS=$7

# Download files if newer than local.
if [[ $(curl -s -O --netrc-file "$PASS" -w "%{http_code}" -z "$CERT" "$URL/$CERT") -eq 304 ]]; then
   echo "No new certificate issued. Nothing to do!"
   exit 1
fi
curl -s -O --netrc-file "$PASS" -z "$INTERMEDIATE" "$URL/$INTERMEDIATE"

# Is the certificate chain valid?
openssl verify -CAfile "$CACERTS" -untrusted "$INTERMEDIATE" "$CERT"

# Do the private keys and certificates belong together?
openssl x509 -in "$CERT" -pubkey | \
   sed -n '/-----BEGIN PUBLIC KEY-----/,/-----END PUBLIC KEY-----/p' | \
   cmp - "${PUBKEY}"

# Has the Let's Encrypt certificate been recently issued (validity >= 80 days)?
openssl x509 -checkend 6912000 -noout -in "$CERT"

# Are the certificates issued for the correct domain names?
(openssl x509 -noout -subject -in "$CERT" | awk -F'CN=' '{print $2}' | \
   awk -F'/' '{print $1}'; \
   openssl x509 -noout -text -in "$CERT" | grep "^[[:space:]]*DNS:" | \
   xargs | tr ' ' '\n' | grep ^DNS | sed 's/^DNS://' | sed 's/,$//')| \
   sort | uniq | cmp - "$DOMAINS"

代码可以通过cronjob运行:

0 1 * * * /usr/local/bin/update_cert.sh >/dev/null 2>&1

update_cert.sh的内容可能是:

#!/bin/bash
( cd /path_to_workdir && \
   su - james -c "./check_cert.sh https://www.example.org intermediate.pem ecdsa.pem ecdsa_pubkey.pem /etc/ssl/certs/ca-certificates.crt domains.txt pass.txt" && \
   su - james -c "./check_cert.sh https://www.example.org intermediate.pem rsa.pem rsa_pubkey.pem /etc/ssl/certs/ca-certificates.crt domains.txt pass.txt" && \
   cat ecdsa.pem intermediate.pem > /etc/nginx/ssl/ecdsa_bundle.pem ) && \
   cat rsa.pem intermediate.pem > /etc/nginx/ssl/rsa_bundle.pem ) && \
/etc/init.d/nginx reload

0 个答案:

没有答案
相关问题