TLS/SSL証明書のファイル形式（PEMとDER）

TLS/SSL証明書のファイル形式として、バイナリで表現した`DER (Distinguished Encoding Rules)`形式とテキストで表現した`PEM (Privacy Enhanced Mail)`形式があります。

（その他にも`jks`、`PKCS#7`、`PKCS#12`等ありますが、こちらは複数の証明書や秘密鍵等をひとつのファイルとして扱うのでまた別の話ということで…。）

`DER`形式から`PEM`形式へ、`PEM`形式から`DER`形式へ変換する方法をここに残しておきます。

# 1. 環境

+ OS : CentOS Linux release 8.5.2111
+ OpenSSL：OpenSSL 1.1.1k FIPS 25 Mar 2021

```console:実行結果
[root@centos85 ~]# cat /etc/redhat-release
CentOS Linux release 8.5.2111
[root@centos85 ~]# openssl version
OpenSSL 1.1.1k  FIPS 25 Mar 2021
[root@centos85 ~]#
```

# 2. DER形式とPEM形式

 + DER (Distinguished Encoding Rules) 形式
     + バイナリ形式
     + ASN.1（抽象構文表記法）で定義されており、データをバイナリで表現
     + 
 + PEM (Privacy Enhanced Mail) 形式
     + テキスト形式
     + DERをBase64でエンコードし、`-----BEGIN`行と`-----END`行で囲ったもの

# 3. DER形式からPEM形式（PEM形式からDER形式）に変換

以下のコマンドでDER形式からPEM形式（PEM形式からDER形式）に変換することができます。

`openssl x509 -inform <変換前の形式 (DER or PEM)> -in <変換前のファイル> -outform <変換後の形式 (DER or PEM)> -out <変換後のファイル>`

qiitaの証明書をDER形式からPEM形式へ変換するコマンドの実行例は以下となります。

```console:実行結果 (DER -> PEM)
[root@centos85 cert]# openssl x509 -inform DER -in ./qiita.der -outform PEM -out qiita.pem
[root@centos85 cert]#
```

qiitaの証明書をPEM形式からDER形式へ変換するコマンドの実行例は以下となります。

```console:実行結果 (PEM -> DER)
[root@centos85 cert]# openssl x509 -inform PEM -in ./qiita.pem -outform DER -out qiita.der
[root@centos85 cert]#
```

# 4. BASE64エンコード、デコードで変換を確認

以下の`base64`コマンドで`qiita.der`をBASE64でエンコードしてみます。

`base64 qiita.der > qiita.base64`

```console:実行結果
[root@centos85 cert]# base64 qiita.der > qiita.base64
[root@centos85 cert]# cat qiita.base64
MIIFyjCCBLKgAwIBAgIQCo7P52Whdeaiv2PRExlsRjANBgkqhkiG9w0BAQsFADA8MQswCQYDVQQG
EwJVUzEPMA0GA1UEChMGQW1hem9uMRwwGgYDVQQDExNBbWF6b24gUlNBIDIwNDggTTAzMB4XDTIz
MTEwNDAwMDAwMFoXDTI0MTIwMjIzNTk1OVowFDESMBAGA1UEAxMJcWlpdGEuY29tMIIBIjANBgkq
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8JVFH4sZ4xMHiwU1V0+Jxs59GzXy4X3Z5xYBUrZQ2Zrh
lQosQd1ymcPiiKwg4U8cWd2BPhiZbZxror3U+GUQBM5O40BtYAgOeekquzq2IlDp2PrVpuZ5s8ts
LHHVfiR/OnSx3itdJfGMR9mnhHIU3+2sg+JQH19M/+dYGfBo0FTZ75K5eOsDL5voMpaqLASWyhtM
kVW3YCevTkeuFb75jt4tIb0A9UibuuR5rSC5bMyTjXmJbAz9QdcALInrV5p6BM7k/J7h2adhPkEg
IN517+pGYR3m+1dOJ9Xr8TRkxR6sH9xNow2DzfjnhMfqQdIyfmst8Qp1OTKAZyU7p0RG+QIDAQAB
o4IC7jCCAuowHwYDVR0jBBgwFoAUVdkYX9IczAHhWLS+q9lVQgHXLgIwHQYDVR0OBBYEFFvW8Id3
WRDaSoXYg0YFzIK9gYnZMCEGA1UdEQQaMBiCCXFpaXRhLmNvbYILKi5xaWl0YS5jb20wEwYDVR0g
BAwwCjAIBgZngQwBAgEwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF
BQcDAjA7BgNVHR8ENDAyMDCgLqAshipodHRwOi8vY3JsLnIybTAzLmFtYXpvbnRydXN0LmNvbS9y
Mm0wMy5jcmwwdQYIKwYBBQUHAQEEaTBnMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5yMm0wMy5h
bWF6b250cnVzdC5jb20wNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQucjJtMDMuYW1hem9udHJ1c3Qu
Y29tL3IybTAzLmNlcjAMBgNVHRMBAf8EAjAAMIIBfQYKKwYBBAHWeQIEAgSCAW0EggFpAWcAdwDu
zdBk1dsazsVct520zROiModGfLzs3sNRSFlGcR+1mwAAAYuXvz6NAAAEAwBIMEYCIQDnYMeBM8b8
BAH6AamwyHTYbhiLEh+sLNWxfx3BgQ2LbgIhAMVkf5WW2cL27oV/9dI7FyMkYRI11rn5F69ER+6w
1lzOAHUASLDja9qmRzQP5WoC+p0w6xxSActW3SyB2bu/qznYhHMAAAGLl78+YgAABAMARjBEAiAG
/uajdrmwbfPdgyqcxVa190yd1/y6e7h3JFkvPh6QKgIgQYky0xsB+ONk50IWIbwBU5ouVQirPPiQ
kS2inAi6Nw8AdQDatr9rP7W2Ip+bwrtca+hwkXFsu1GEhTS9pD0wSNf7qwAAAYuXvz5WAAAEAwBG
MEQCIG27h6mTLbAIrYillfquap/JFk5ickO3a978lXiOHqjrAiAiySkK0raMoSJRmGZ1x+/MnLZ6
U6IobYB76/Q6VEd/5jANBgkqhkiG9w0BAQsFAAOCAQEAYXrXPfM9WK/YsrxrTfFmMLIO0diTPRt9
04SRPBScYS4HdM4RzZVVfzQDrYeewefW+gPLg5TMflOPH8PnH5bvfE7h9ZIcM/1I6NwGByFPWoaF
TZM79sdAcEIq1og1+MMTaNFPVbBxCEw3JGQ0KZlqov+qFx0O7sfHj3Ogr1Hqz1nlZLJP7GwYigtM
QGPP8WPaQFlbLI2/cupN54J0blt5ta0KvQ4l+13+YbGEiuscdkHZ7B1TplADYcSGrQuleCgUk8LR
BWisQWV0lbvAqe1tp+ux91TE9uch2ig/vz8ohqg4jOB6XSOHklaV09ZN/WLBJwviv80u2KAKfbGt
vc4+Hw==
[root@centos85 cert]#
```

`diff`コマンドで以下を比較してみます。
+ `qiita.base64`から改行を取り除いたもの
+ `qiita.pem`の`-----BEGIN CERTIFICATE-----`と`-----END CERTIFICATE-----`の間を抽出し改行を取り除いたもの

`diff <(cat qiita.base64 | tr -d '\r' | tr -d '\n') <(sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' qiita.pem | sed '1d;$d' | tr -d '\r' | tr -d '\n')`

```console:実行結果
[root@centos85 cert]# diff <(cat qiita.base64 | tr -d '\r' | tr -d '\n') <(sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' qiita.pem | sed '1d;$d' | tr -d '\r' | tr -d '\n')
[root@centos85 cert]#
```

DER形式をBASE64でエンコーディングした内容とPEM形式の内容が一致することがわかります。

次に、以下の`base64`コマンドで`qiita.pem（BEGIN、ENDの行を取り除き改行を取り除いたもの）`をBASE64でデコードしてみます。

`base64 -d <(sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' qiita.pem | sed '1d;$d' | tr -d '\r' | tr -d '\n') > qiita.bin`

`diff`コマンドで`qiita.bin`と`qiita.der`を比較してみます。

```console:実行結果
[root@centos85 cert]# diff qiita.der qiita.bin
[root@centos85 cert]#
```

PEM形式をBASE64でデコーディングした内容とDER形式の内容が一致することがわかります。

# 参考
+ [メモ - openssl x509コマンド - /OpenSSL/はじめに](https://memo.open-code.club/OpenSSL/%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB/%E5%85%AC%E9%96%8B%E9%8D%B5%E8%A8%BC%E6%98%8E%E6%9B%B8.html "メモ - openssl x509コマンド - /OpenSSL/はじめに")
+ [SSL証明書変換：証明書のフォーマットを変換する | ラッコツールズ🔧](https://rakko.tools/tools/49/  "SSL証明書変換：証明書のフォーマットを変換する | ラッコツールズ🔧")
+ [【.pem/.crt】証明書や秘密鍵の拡張子はなぜ違う事があるのか | 株式会社ビヨンド](https://beyondjapan.com/blog/2023/04/why-certificate-extension/ "【.pem/.crt】証明書や秘密鍵の拡張子はなぜ違う事があるのか | 株式会社ビヨンド")
+ [【Windows】証明書のエクスポート形式の違い, 秘密キーのセキュリティについて | SEの道標](https://milestone-of-se.nesuke.com/sv-basic/windows-basic/certificate-export-format/ "【Windows】証明書のエクスポート形式の違い, 秘密キーのセキュリティについて | SEの道標")
+ [SSLサーバー証明書 : 証明書ファイルの種類とopensslでの変換方法 | DigiCert](https://rms.ne.jp/sslserver/basis/file_types/ "SSLサーバー証明書 : 証明書ファイルの種類とopensslでの変換方法 | DigiCert")
+ [base64 コマンド | コマンドの使い方(Linux) | hydroculのメモ](https://hydrocul.github.io/wiki/commands/base64.html "base64 コマンド | コマンドの使い方(Linux) | hydroculのメモ")

---

以上