手元の証明書ファイルの期限を確認したい

サーバに配置した証明書ファイルや、認証局から受け取ったばかりの証明書ファイルについて、有効期限や発行対象を確認したい場面がある。証明書はPEM形式であればテキストファイルだが、中身はBase64でエンコードされているためそのまま読んでも内容は分からない。

openssl x509コマンドを使うと、証明書ファイルから必要な項目だけを取り出して表示できる。

$ openssl x509 -in cert.crt -noout -subject -dates
subject=C=JP, ST=Tokyo, O=Example Inc., CN=example.com
notBefore=Aug 14 22:12:02 2026 GMT
notAfter=Aug 14 22:12:02 2027 GMT

notAfterが有効期限である。上記の例では2027年8月14日22時12分02秒(UTC)に期限が切れる。

指定しているオプションはそれぞれ以下の通り。

オプション説明
-in cert.crt読み込む証明書ファイルを指定する
-nooutエンコードされた証明書本体の出力を抑止する
-subject証明書の発行対象(コモンネームや組織名)を表示する
-dates有効期間の開始日時(notBefore)と終了日時(notAfter)を表示する

-nooutを省略すると-----BEGIN CERTIFICATE-----から始まる証明書本体も一緒に出力される。期限だけを見たい場合は必ず付ける。

本記事の実行例はOpenSSL 3.5のもの。subject=の表示はバージョンによって異なり、OpenSSL 3.2より前はsubject=C = JP, ST = Tokyo, O = Example Inc., CN = example.comのように等号の前後に空白が入る。Ubuntu 22.04やAmazon Linux 2023などが採用するOpenSSL 3.0系も空白ありの表示である。

表示する項目を絞る

有効期限だけを確認したい場合は-enddateを指定する。開始日時だけなら-startdateである。

$ openssl x509 -in cert.crt -noout -enddate
notAfter=Aug 14 22:12:02 2027 GMT

発行者を確認したい場合は-issuerを指定する。自己署名した証明書では-subjectと同じ内容が表示される。プライベートCAで署名した証明書では、発行元のCAの情報が表示される。

$ openssl x509 -in cert.crt -noout -issuer
issuer=C=JP, ST=Tokyo, O=Example Inc., CN=example.com

証明書が対応するドメイン名を確認するには-ext subjectAltNameを指定する。最近のブラウザはコモンネームではなくSAN(Subject Alternative Name)でドメインの一致を判定するため、対象ドメインの確認にはSANを見る。

$ openssl x509 -in cert.crt -noout -ext subjectAltName
X509v3 Subject Alternative Name:
    DNS:example.com, DNS:www.example.com

証明書のすべての項目を読みたい場合は-textを指定する。

$ openssl x509 -in cert.crt -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            44:0e:f7:ec:b5:24:75:7d:54:14:07:fa:70:f8:18:26:d9:ad:85:e5
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=JP, ST=Tokyo, O=Example Inc., CN=example.com
        Validity
            Not Before: Aug 14 22:12:02 2026 GMT
            Not After : Aug 14 22:12:02 2027 GMT
        Subject: C=JP, ST=Tokyo, O=Example Inc., CN=example.com
()

日時の表示形式を変える

デフォルトのAug 14 22:12:02 2027 GMTの形式は他のコマンドで扱いにくい。OpenSSL 3.0以降では-dateopt iso_8601を指定するとISO 8601形式で表示できる。OpenSSL 1.1.1ではx509: Unrecognized flag dateoptとなり使えない。

$ openssl x509 -in cert.crt -noout -dates -dateopt iso_8601
notBefore=2026-08-14 22:12:02Z
notAfter=2027-08-14 22:12:02Z

期限切れが近いかを判定する

監視スクリプトなどで期限切れの接近を検知したい場合は-checkendを使う。引数に秒数を指定すると、その秒数以内に期限が切れるかどうかを終了コードで返す。

$ openssl x509 -in cert.crt -noout -checkend 2592000
Certificate will not expire
$ echo $?
0

期限が切れる場合はCertificate will expireと表示され、終了コードは1になる。

$ openssl x509 -in cert.crt -noout -checkend 31536000
Certificate will expire
$ echo $?
1

上記の例では30日(2592000秒)以内には切れないが、365日(31536000秒)以内には切れると判定されている。-checkend 0とすれば、現時点で期限切れかどうかを判定できる。

終了コードで結果が分かるため、シェルスクリプトの条件分岐にそのまま組み込める。

$ if ! openssl x509 -in cert.crt -noout -checkend 2592000 > /dev/null; then
    echo "cert.crt expires within 30 days"
  fi

ファイルが存在しない場合や読み取り権限がない場合も終了コードは1になる。監視スクリプトで使う場合は、エラー出力の有無もあわせて確認するとよい。

DER形式の証明書を読む

バイナリのDER形式を読む場合は-inform derを指定する。拡張子は.derのほか.cerも使われる。ただし.cerはPEM形式でも使われるため、拡張子だけでは判別できない。

$ openssl x509 -in cert.der -inform der -noout -subject -dates
subject=C=JP, ST=Tokyo, O=Example Inc., CN=example.com
notBefore=Aug 14 22:12:02 2026 GMT
notAfter=Aug 14 22:12:02 2027 GMT

OpenSSL 3.0以降は-informを省略しても形式を自動判別するため、DER形式でもそのまま読める。OpenSSL 1.1.1ではPEM形式として扱われ、以下のエラーになる。

unable to load certificate
277010640747592:error:0909006C:PEM routines:get_name:no start line:crypto/pem/pem_lib.c:745:Expecting: TRUSTED CERTIFICATE

なお、OpenSSL 3.0以降でもPEM形式のファイルに-inform derを指定すると読み込みに失敗する。バージョンによる差を意識せずに済むよう、DER形式のときだけ-inform derを付けるとよい。

macOS標準のopensslはLibreSSL

macOSの/usr/bin/opensslはOpenSSLではなくLibreSSLである。

$ /usr/bin/openssl version
LibreSSL 3.3.6

LibreSSLでは-ext-dateoptが実装されておらず、unknown option -extのようなエラーになる。DER形式の自動判別にも対応しないため-inform derの指定が必要である。subject=の表示形式も異なり、以下のようにスラッシュ区切りになる。

$ /usr/bin/openssl x509 -in cert.crt -noout -subject
subject= /C=JP/ST=Tokyo/O=Example Inc./CN=example.com

OpenSSL本体を使いたい場合はHomebrewでインストールする。

$ brew install openssl
$ $(brew --prefix openssl)/bin/openssl version

公開中のサーバの証明書を確認する

ファイルではなく稼働中のサーバの証明書を確認したい場合はopenssl s_clientで取得し、パイプでopenssl x509に渡す。

$ openssl s_client -connect example.com:443 < /dev/null 2>/dev/null | openssl x509 -noout -subject -dates
subject=CN=example.com
notBefore=Jul 29 22:10:08 2026 GMT
notAfter=Oct 27 22:17:21 2026 GMT

-inを指定しない場合、openssl x509は標準入力から証明書を読む。openssl s_clientの出力には証明書以外の情報も含まれるが、-----BEGIN CERTIFICATE-----のブロックが解釈されるためそのまま渡してよい。

openssl s_clientの詳細や中間証明書を含めた確認方法は【openssl】指定したURLの証明書をコマンドで確認する を参照。

参考