【.pem/.crt】証明書や秘密鍵の拡張子はなぜ違う事があるのか
目次
皆様こんにちは。
休日は12時間くらい寝てしまう、システムソリューション部所属のなかです。
ショートスリーパーに憧れますね。
今回は以前より書いている「opensslコマンドでSSL証明書を確認する」記事の派生です。
下記記事内で、「◯本記事で使用する拡張子」という記載で使用する拡張子について明記しました。
これは「証明書や鍵の拡張子は環境・人によって違うことがあるため」に書いた前置きです。
そうなると、「証明書や秘密鍵の拡張子はなぜ違う事があるのか」と思う方がいるかと思いますので、
「違う事がある理由」について「拡張子の種類」「データ形式」も交えてご説明していきたいと思います。
合わせて「ではどう対応すべきだろう」と悩む点に関しての個人的な対応策も考えてみました。
実行環境
- Linux環境
OS:AlmaLinux release 8.5 (WSL2環境)
Shell:Bash
OpenSSL 1.1.1k FIPS 25 Mar 2021 - Windows環境
OS:Windows11 Pro (バージョン:22H2)
言語設定を日本語に変更
「エンコードの形式を表す拡張子」と「中身を表す拡張子」
現場や環境が変われば、使われているSSL証明書や秘密鍵の拡張子が変わることがあります。
「.pem」・「.der」で統一されていたり、「.crt」・「.key」等で分かれていたり……
ひょっとすると混在しているかもしれません。
これは見出しのように「エンコードの形式を表す拡張子(.pem)(.der)」と「中身を表す拡張子(.crt)(.key)」が存在しているからです。
「エンコードの形式を表す拡張子」(.pem)(.der)
エンコード(符号化・変換)の形式(フォーマット)を表すための拡張子です。
そのため、証明書や秘密鍵で共通して使用されている場合はファイル名や中身で判断する必要があります。
「.pem」はPEM形式のエンコード形式だと表す拡張子で、「.der」はDER形式のエンコード形式を表す拡張子です。
これらの一般的なエンコード形式について説明いたします。
DER
ASN.1 というネットワークでの通信を行う際データ構造を定義するための標準的な記法があり、
その記法に従ったデータをバイナリデータに変換させた形式の1つがこのDER形式です。
古い仕様のソフトウェアだとDER形式の証明書にしか対応していない物もあるようです。
Windows(OS側)でよく使われています。
PEM
上記のDER形式をBase64方式にエンコードしたものが一般的によく使用されているPEM形式です。
Base64形式はアルファベットの大文字・小文字と数字で表現されるデータ表現方式で、
要するにデータを文字列(テキスト)化しています。
PEM形式は先頭に「-----BEGIN (内容物の名前)-----」
末尾に「-----END (内容物の名前)-----」という文字列で区切り、
その間にBase64で表現された中身のバイナリデータが記載されている形となっています。
Base64である事で以下のメリットが生まれています。
・編集しやすい
テキストデータであるため、テキストエディタで簡単に表示・編集等が行なえます。
DERの場合はバイナリエディタが必要になり編集や確認が容易ではありません。
・連結できる
この区切り形式を取っていれば1つのファイル内に複数のデータを格納できるのが特徴的です。
Apache2.4.8以降、証明書と中間証明書が一体化した物があると前回の記事で説明しました。
1つのファイルで証明書や中間証明書や秘密鍵をまとめる事ができるのはPEM形式の利点です。
※ただし結合順は決まっています。
Linuxで一般的に使われているSSLのソフトウェアである「openssl」でPEM形式がデフォルト設定となっています。
そのため、Linux環境で一般的な形式で複数のデータを格納できるコンテナ形式です。
Tips:証明書の規格
証明書はX.509という公開鍵基盤の標準規格が存在し、基本的にこれに準じています。
ANS.1 という記法はこの規格で規定されたデータ構造を定義するために使用されている形です。
X.509は元々ITUが定めたデジタル証明書の標準ですが、
現在はIETFがプロファイル化したRFC5280の規格の事を指しています。
「中身を表す拡張子」(.crt)(.key)等
中身(役割)を表す際に拡張子です。
※拡張子はわりと自由のため、複数存在しております。
.crt /.cer
証明書を表す際に使われている拡張子です。
.crtはLinux環境でよく使われており、
digicert等の認証局でApache+OpenSSL構成用で発行した際にはこの拡張子が使われます。
.cerはWindows環境でよく使われており、
digicert等の認証局でMicrosoft IIS 構成用で発行した際に使われる事があります。
慣習的に環境によって拡張子が違うだけで、
どの拡張子でも中身のデータがDER(バイナリ)かPEM(テキスト)かの形式は問いません。
.key
秘密鍵を表す際によく使われている拡張子です。
更新作業では基本的に触りませんが、
公開鍵の場合は秘密鍵と区別するため「.pub」を使うことが一般的です。
.ca
中間証明書を表す際によく使われている拡張子です。
ただ、.crtが証明書の場合に.cerを中間証明書に使用するといったケースもあり
証明書の拡張子ほど慣習化していないというのが筆者の印象です。
+α:証明書を表す拡張子(.p7b)(.p12)
これらはカテゴリ的には「中身を表す拡張子」に含まれるのですが、
対応していないソフトウェアが多く、Linux環境では基本的に使用頻度が低いため
同じ項目で説明すると理解しにくくなると判断して分けています。
※macOSでも利用されています。
PKCS
PKCS (Public-Key Cryptography Standards) という、公開鍵暗号標準群が存在しています。
PKCS#7 とPKCS#12 は 証明書に関連した標準で、
その標準に対応した物の拡張子が .p7bと.p12です。
※厳密にはPKCS#12だと.pfxといった拡張子等も存在していますが説明としては省略します。
証明書を定めた標準ではなく、証明書を格納(コンテナ)するデータ形式を定めた物です。
これらはWindowsのWebサーバーであるMicrosoft IIS が対応しているため、
WindowsServer環境で利用する事が多い形式です。
OpenSSLコマンドなどでPEM形式などに変換する事も可能です。
.p7b
PKCS#7 という暗号化の標準で作成された証明書です。
証明書と中間証明書(+ルート証明書)を1つにまとめることは可能です。
.p12
PKCS#12 という暗号の標準で作成された証明書です。
証明書に秘密鍵を1つのファイルに格納できるようになった物です。
ただし使用するにあたりパスワードを設定する必要があるという仕様です。
拡張子の混在問題
作業者が普段と違う人であったために意図せずに違う性質の拡張子を使用したり、
認証局が変わった事でデフォルトで発行される拡張子が代わった等の理由で拡張子の混雑が発生します。
大それた問題では無いのですが、拡張子が混在されると「作業者的にちょっと面倒」です。
これは環境の構築担当者と運用者が違う事は一般的ですが、
証明書の発行対応者と更新作業者が違う事もあるからです。
そのため、拡張子が混在すると以下のような事が発生したりします。
- 環境内で拡張子がバラバラだと都度confで指定のファイル名を確認する必要がある
- 関連するソフトウェア的に意図があるのかと考えて、発行対応者に確認しにいく可能性
- 見栄えが悪い(主観)
どう対応すべきなのか
ルール化で「拡張子は中身を表す物を使用する」と定めて統一
「運用ルール」もしくは「環境のドキュメント」に使用する拡張子を明示的に記載するのが良いと思われます。
運用によってはSSL証明書の発行業務を行う人が事務員の方であったりして、
そもそもconfも見れない事がありますので一般的なルールとして定めて文章化しておく方が良いかなと筆者個人は考えます。
余談:そもそもなぜ拡張子が複数存在しているのか
そもそも拡張子は「ソフトウェア側がファイル形式を識別するための物」の名付けであって、絶対的な物では無いからです。
あくまで、データ的な規格や仕様ではなくソフトウェア側の概念です。
当たり前ですが、画像データ(.jpg)を「.txt」の拡張子に変更しても、
「ソフトウェアがテキストデータだと解釈して開く」だけであって
中身のJPEGデータがテキストデータに変わる訳ではありません。
勝手に書き換えられるように、拡張子とは任意で設定できる物です。
要するに、証明書等は規格としてデータの構造が定められているだけであり
拡張子が厳密に規定されているわけではありません。
Tips:拡張子の概念はそもそもLinuxには存在していない
Linuxにおいてはそもそも拡張子でファイル形式を識別していません、つまり拡張子という概念が存在していません。
あくまでLinuxではユーザー(人間)が管理上の識別・利便性のためにファイル名に拡張子を付けている形となります。
「拡張子」の概念は絶対的ではなく、OSによって仕様が大きく違っている例ですね。
※LinuxでもGUI環境化させるソフトウェアを導入した際は、
そのソフトウェア側で拡張子を認識して判断する機能が追加される事はあります。
最後に
何気なく以前の記事のTips的なところから掘り下げて書き始めたましたが、
想像以上に説明が難しく、また前提となる知識が多い内容でした。
説明が長くなりましたが現場での混乱を減らすため、
「拡張子は揃えておこう」くらいの認識があれば良いかなと筆者は思います。
この記事を読んだ方に多少でも役に立つ知識となれれば幸いです。
参考資料
Let's Encryptの公式ドキュメント / ASN.1 と DER へようこそ
https://letsencrypt.org/ja/docs/a-warm-welcome-to-asn1-and-der/
digicertの公式サイト/ [CertCental]サーバ証明書 インストール手順
https://knowledge.digicert.com/ja/jp/solution/SOT0002.html
RFC 5280
https://www.rfc-editor.org/rfc/rfc5280
ITU-T Recommendations
https://www.itu.int/ITU-T/recommendations/rec.aspx?rec=X.509
RFC 7468
https://www.rfc-editor.org/rfc/rfc7468#section-5.3
※5.3 の部分でファイル拡張子について言及されていますが、
「広く普及している事実上の代替手段を明確に示しているにすぎません。(日本語訳)」
と末尾に書かれており、規格内で厳密に規定している訳ではないようです。