Linux 如何从PEM编码的证书确定SSL证书过期日期?

Linux 如何从PEM编码的证书确定SSL证书过期日期?,linux,bash,ssl,openssl,certificate,Linux,Bash,Ssl,Openssl,Certificate,如果我在Mac或Linux中有一个实际的文件和一个Bash shell,我如何查询证书文件的到期时间?不是一个网站,而是证书文件本身,假设我有csr、密钥、pem和链文件。Withopenssl: openssl x509 -enddate -noout -in file.pem 输出格式如下: notAfter=Nov 3 22:23:50 2014 GMT 另请参阅如何轻松检查证书是否已过期,或是否将在特定时间段内过期,而无需解析上述日期。如果您只想知道证书是否已过期(或将在接下来的N

如果我在Mac或Linux中有一个实际的文件和一个Bash shell,我如何查询证书文件的到期时间?不是一个网站,而是证书文件本身,假设我有csr、密钥、pem和链文件。

With
openssl

openssl x509 -enddate -noout -in file.pem
输出格式如下:

notAfter=Nov  3 22:23:50 2014 GMT

另请参阅如何轻松检查证书是否已过期,或是否将在特定时间段内过期,而无需解析上述日期。

如果您只想知道证书是否已过期(或将在接下来的N秒内过期),
openssl x509
-checkend
选项将告诉您:

if openssl x509 -checkend 86400 -noout -in file.pem
then
  echo "Certificate is good for another day!"
else
  echo "Certificate has expired or will do so within 24 hours!"
  echo "(or is invalid/not found)"
fi
这样就不必自己进行日期/时间比较

在上面的示例中,
openssl
将返回退出代码
0
(零),如果证书尚未过期,并且在接下来的86400秒内不会这样做。如果证书已过期或已过期-或其他错误,如无效/不存在文件-返回代码为
1

(当然,它假定时间/日期设置正确)


请注意,较旧版本的openssl有一个bug,这意味着如果在
checkend
中指定的时间太长,则将始终返回0()。

下面是我的bash命令行,它按证书过期的顺序列出多个证书,最近的一个证书将首先过期

for pem in /etc/ssl/certs/*.pem; do 
   printf '%s: %s\n' \
      "$(date --date="$(openssl x509 -enddate -noout -in "$pem"|cut -d= -f 2)" --iso-8601)" \
      "$pem"
done | sort
样本输出:

2015-12-16: /etc/ssl/certs/Staat_der_Nederlanden_Root_CA.pem
2016-03-22: /etc/ssl/certs/CA_Disig.pem
2016-08-14: /etc/ssl/certs/EBG_Elektronik_Sertifika_Hizmet_S.pem
对MacOSX(ElCapitan)来说,对尼古拉斯的例子的这种修改对我来说是有效的

for pem in /path/to/certs/*.pem; do
    printf '%s: %s\n' \
        "$(date -jf "%b %e %H:%M:%S %Y %Z" "$(openssl x509 -enddate -noout -in "$pem"|cut -d= -f 2)" +"%Y-%m-%d")" \
    "$pem";
done | sort
样本输出:

2014-12-19: /path/to/certs/MDM_Certificate.pem
2015-11-13: /path/to/certs/MDM_AirWatch_Certificate.pem

macOS不喜欢我的系统上的
--date=
--iso-8601
标志。

这里有一个bash函数,假设您使用的是DNS循环,它会检查所有服务器。请注意,这需要GNU日期,在Mac OS上不起作用

function check_certs () {
  if [ -z "$1" ]
  then
    echo "domain name missing"
    exit 1
  fi
  name="$1"
  shift

  now_epoch=$( date +%s )

  dig +noall +answer $name | while read _ _ _ _ ip;
  do
    echo -n "$ip:"
    expiry_date=$( echo | openssl s_client -showcerts -servername $name -connect $ip:443 2>/dev/null | openssl x509 -inform pem -noout -enddate | cut -d "=" -f 2 )
    echo -n " $expiry_date";
    expiry_epoch=$( date -d "$expiry_date" +%s )
    expiry_days="$(( ($expiry_epoch - $now_epoch) / (3600 * 24) ))"
    echo "    $expiry_days days"
  done
}
输出示例:

$ check_certs stackoverflow.com
151.101.1.69: Aug 14 12:00:00 2019 GMT    603 days
151.101.65.69: Aug 14 12:00:00 2019 GMT    603 days
151.101.129.69: Aug 14 12:00:00 2019 GMT    603 days
151.101.193.69: Aug 14 12:00:00 2019 GMT    603 days
如果(出于某种原因)您希望在Linux中使用GUI应用程序,请使用
gcr viewer
(在大多数发行版中,它是由包
gcr
安装的(否则在包
gcr viewer
中)


如果域证书将在一段时间后过期(例如15天),则对真/假进行一行检查:


opensslx509-checkend$((24*3600*15))-noout-in与公认的答案相同,但请注意,它甚至适用于
.crt
文件,而不仅仅是
.pem
文件,以防您无法找到
.pem
文件位置

openssl x509 -enddate -noout -in e71c8ea7fa97ad6c.crt
结果:

notAfter=Mar 29 06:15:00 2020 GMT

我已经制作了一个与之相关的bash脚本来检查证书是否过期。如果需要,您可以使用相同的

脚本

自述文件


x509
实用程序中还内置了
-startdate
-enddate
选项。他们将为您保存
grep
。如果文件不是pem格式,也可以这样做。适用于服务器。非常好!这就是我想要的。现在我有一个证书的概述,我必须很快更新。将其保存为我的主文件夹中的checkcerts.sh,以便我可以定期检查。下一件事将是有一个CRON作业,每月检查并通过电子邮件发送需要更新的证书。非常有用,谢谢。我使用这个cronjob
0 7**1/path/to/cert.sh | mail-s“certbot”my@email.com
如果您没有制作.pem文件,而只有刚刚制作并从Apple Dev站点下载的
.cer
证书,您会怎么做?要确定证书当前是否过期,请使用0秒的持续时间。省略
-noout
选项以查看使用单个命令而不使用额外逻辑的有用消息。例如,
openssl x509-checkend 0-in file.pem
将给出输出“证书将过期”或“证书将不会过期”,指示证书是否将在零秒后过期。向-checkend提供大于30年(922752000)的值会导致选项异常运行(即使证书在此时间段内过期,也返回0)。令人惊讶的是,osx 10.13.4运行您的shell OK(不要评判我,我今天在osx上只是为了将应用程序推送到应用商店…很快将引导回linux;-)@ScottStensland我们正在评判:-P.我经常使用Mac,但Linux确实要好得多。非常感谢您的代码snippit!多么烦人的任务:),我希望openssl有unixtime时间戳标志。对于那些使用alpine Linux容器的人,您的
expiration\u date
值需要将时区名称从其末尾删除。在管道末端添加一个额外的
切口
:切口-d'-f 1-4
openssl x509 -enddate -noout -in e71c8ea7fa97ad6c.crt
notAfter=Mar 29 06:15:00 2020 GMT