証明書をPEM形式からDER形式に、DER形式からPEM形式に変換したいときは、openssl x509 -outformを使う。

$ openssl x509 -in cert.pem -outform DER -out cert.der

DER形式をPEM形式に戻すには、-inform DERで入力の形式を指定する。

$ openssl x509 -inform DER -in cert.der -out cert.pem

-outformを省略すると、出力はPEM形式になる。

実行例はUbuntu 24.04のOpenSSL 3.0.13のもの。

PEMとDERの違い

証明書のファイル形式は、主に2つある。

形式中身見分け方主な拡張子
PEMDERをBase64にしたテキスト-----BEGIN CERTIFICATE-----で始まる.pem、.crt、.cer
DERバイナリテキストエディターで開くと文字化けする.der、.cer、.crt

.cerや.crtはどちらの形式でも使われるため、拡張子では判別できない。先頭を確認する。

$ head -c 27 cert.pem
-----BEGIN CERTIFICATE-----
$ od -An -tx1 cert.der | head -1
 30 82 01 9c 30 82 01 42 a0 03 02 01 02 02 14 3e

DER形式は、30 82(ASN.1のSEQUENCE)で始まる。

PEM形式からDER形式に変換しても、データの内容は変わらない。DERをPEMに戻すと、元のPEMと完全に一致する。

$ openssl x509 -inform DER -in cert.der -out cert2.pem
$ cmp cert.pem cert2.pem && echo same
same

DER形式の証明書を読み込む

DER形式の証明書をopenssl x509で表示する場合は、-inform DERを付ける。

$ openssl x509 -inform DER -in cert.der -noout -subject
subject=CN = example.test

OpenSSL 3.0以降は、-informを省略してもDER形式を自動判別して読み込める。macOS標準の/usr/bin/openssl(LibreSSL 3.3.6)は自動判別できず、-inform DERを付けないとエラーになる。

$ /usr/bin/openssl x509 -in cert.der -noout -subject
unable to load certificate
...Expecting: TRUSTED CERTIFICATE

どのバージョンでも動くように、DER形式では-inform DERを付けておく。

PKCS#7形式に変換する

複数の証明書を1つのファイルにまとめる形式として、PKCS#7(.p7b、.p7c)がある。openssl crl2pkcs7で作る。

$ openssl crl2pkcs7 -nocrl -certfile cert.pem -out cert.p7b
$ head -1 cert.p7b
-----BEGIN PKCS7-----

PKCS#7形式から証明書を取り出すには、openssl pkcs7 -print_certsを使う。

$ openssl pkcs7 -in cert.p7b -print_certs -out certs.pem

出力ファイルには、各証明書のPEMの前にsubject=とissuer=の行が付く。openssl x509はPEM以外の行を読み飛ばすため、そのまま読み込める。

秘密鍵も含めてまとめる形式には、PKCS#12(.p12、.pfx)もある。

フィンガープリントを表示する

-fingerprintは、証明書のDER形式に対するハッシュ値を表示する。証明書が同じものかを確認するときや、サイトが公開しているフィンガープリントと照合するときに使う。

$ openssl x509 -in cert.pem -noout -fingerprint -sha256
sha256 Fingerprint=E1:60:C4:AD:CE:D4:EE:F3:5B:31:79:CA:20:12:D7:72:0B:1F:EE:71:66:C1:B5:D1:00:03:03:10:06:E0:15:6A

ハッシュアルゴリズムを省略すると、OpenSSL 3.xではSHA-1になる。LibreSSL 3.3.6ではSHA-256になる。バージョンによって結果が変わらないように、-sha256を明示する。

$ openssl x509 -in cert.pem -noout -fingerprint
sha1 Fingerprint=15:40:4D:4A:6C:BA:C8:17:31:C4:BA:60:6D:64:71:EB:EA:6F:34:E4

フィンガープリントは、DER形式のデータに対する単純なハッシュ値である。openssl dgstで同じ値を再現できる。

$ openssl x509 -in cert.pem -outform DER | openssl dgst -sha256
SHA2-256(stdin)= e160c4adced4eef35b3179ca2012d7720b1fee7166c1b5d10003031006e0156a

PEM形式のファイルをそのままハッシュしても、同じ値にならない。Base64とヘッダー行を含むためである。

参考: 【openssl】ファイルのハッシュ値を計算する (dgst)

証明書から公開鍵を取り出す

-pubkeyで、証明書に含まれる公開鍵をPEM形式で取り出す。

$ openssl x509 -in cert.pem -noout -pubkey
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----

取り出した公開鍵は、openssl pkey -pubinで内容を確認できる。

参考: 【openssl】秘密鍵から公開鍵を取り出す (pkey)

サブジェクトのハッシュ値を表示する

-hashは、サブジェクトのハッシュ値を8桁の16進数で表示する。/etc/ssl/certs/のように、証明書を[ハッシュ値].0というファイル名で並べたディレクトリ(-CApathで指定するディレクトリ)を作るときに使う。

$ openssl x509 -in cert.pem -noout -hash
8593a23d
$ mkdir certs
$ cp cert.pem certs/$(openssl x509 -in cert.pem -noout -hash).0
$ openssl verify -CApath certs cert.pem
cert.pem: OK

OpenSSL 1.0.0以降と、それ以前(0.9.8)では、ハッシュの計算方法が異なる。古い形式が必要な場合は、-subject_hash_oldを使う。

$ openssl x509 -in cert.pem -noout -subject_hash_old
90179be9

その他の項目を表示する

openssl x509は、-nooutと表示オプションの組み合わせで、必要な項目だけを取り出せる。

オプション表示内容
-subjectサブジェクト
-issuer発行者
-serialシリアル番号
-dates有効期間の開始日時と終了日時
-ext subjectAltNameSANなどの拡張
-purpose証明書の用途
$ openssl x509 -in cert.pem -noout -serial
serial=3EAC40FC1180B5DC74E6CB1603644E35DD3E48DC

有効期限や拡張の確認は、別の記事で説明している。

参考: 【openssl】証明書ファイルの有効期限を確認する

表示形式の違い

-subjectの表示は、バージョンで異なる。

実行環境出力例
OpenSSL 3.0subject=CN = example.test
OpenSSL 3.5、3.6subject=CN=example.test
LibreSSL 3.3.6subject= /CN=example.test

出力をスクリプトで処理する場合は、この違いに注意する。

複数の証明書を含むファイルを扱う

PEM形式のファイルに複数の証明書を連結している場合、openssl x509は先頭の1枚だけを処理する。

$ cat cert.pem cert.pem > two.pem
$ openssl x509 -in two.pem -noout -subject
subject=CN = example.test

すべての証明書を表示するには、openssl pkcs7 -print_certsを使う。

$ openssl crl2pkcs7 -nocrl -certfile two.pem | openssl pkcs7 -print_certs -noout
subject=CN = example.test
issuer=CN = example.test

subject=CN = example.test
issuer=CN = example.test

参考

openssl-x509 - OpenSSL Documentation