自己証明書(通称オレオレ証明書)の作成方法です
1. CA用の秘密鍵を生成
このコマンドは、2048ビットのRSA秘密鍵を生成し、localCA.key
というファイルに保存します。
$ openssl genrsa -out localCA.key 2048
- openssl genrsa: RSA 秘密鍵を生成するコマンド
- -out: 生成した秘密鍵の出力ファイル名 (例: localCA.key)
- 2048: 秘密鍵の長さ (ビット単位) (例: 2048ビット)
2. 秘密鍵と識別情報から証明書署名要求 (CSR) の作成
このコマンドは、以下の情報を設定した CSR を生成し、localCA.csr
というファイルに保存します。
$ openssl req -batch -new -key localCA.key -out localCA.csr \
-subj "/C=jp/ST=Osaka/L=Osaka-shi/O=\"Example Inc\"/OU=Foo/CN=tek"
- openssl req: 証明書署名要求 (CSR) を作成するコマンド
- -batch: 対話形式ではなく、バッチ処理で実行
- -new: 新しい CSR を作成
- -key: 秘密鍵ファイル (例: localCA.key)
- -out: 生成した CSR の出力ファイル名 (例: localCA.csr)
- -subj: 証明書の情報 (Subject) を指定
-subj オプションについて
- 国名 (C): JP
- 都道府県 (ST): Osaka
- 市区町村 (L): Osaka-shi
- 組織名 (O): Example Inc
- 組織単位 (OU): Foo
- コモンネーム (CN): tek
項目は / で区切ります。
組織名 (O) や組織単位 (OU) など、値内にスペースが含まれる場合は、二重引用符 (") で囲みます。
3. 公開鍵が入ったCSRを秘密鍵で自己署名してCA証明書を発行
このコマンドは、localCA.csr
に含まれる情報に基づいて、localCA.key
を用いて自己署名証明書を生成し、localCA.crt
というファイルに保存します。
$ openssl x509 -req -days 3650 -signkey localCA.key -in localCA.csr -out localCA.crt
- openssl x509: 証明書を発行するコマンド
- -in: CSR ファイル (例: localCA.csr)
- -out: 生成した証明書の出力ファイル名 (例: localCA.crt)
- -req: CSR を基に証明書を発行
- -signkey: 秘密鍵ファイル (例: localCA.key)
- -days: 証明書の有効期限 (日数) (例: 3650日) ※運用環境に合わせて設定
- -sha256: ハッシュアルゴリズム (例: SHA-256)
作成されたCA証明書の中身を確認
既存のSSL証明書の内容を表示するためのコマンドです。
$ openssl x509 -text -noout -in localCA.crt
Certificate:
Data:
Version: 1 (0x0)
Serial Number:
70:3c:59:37:c6:cb:dc:f0:5e:16:13:54:98:1c:a5:30:1f:a5:a1:08
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = jp, ST = Osaka, L = Osaka-shi, O = \"Example Inc\", OU = Foo, CN = localhost
Validity
Not Before: Mar 19 21:08:48 2024 GMT
Not After : Mar 17 21:08:48 2034 GMT
Subject: C = jp, ST = Osaka, L = Osaka-shi, O = \"Example Inc\", OU = Foo, CN = localhost
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
4. サーバー用の秘密鍵を生成
このコマンドは、2048ビットのRSA秘密鍵を生成し、localhost.key
というファイルに保存します。
$ openssl genrsa -out localhost.key 2048
5. 秘密鍵と識別情報から証明書署名要求 (CSR)を作成
このコマンドは、以下の情報を設定した CSR を生成し、localhost.csr
というファイルに保存します。
$ openssl req -batch -new -key localhost.key -out localhost.csr \
-subj "/C=jp/ST=Osaka/L=Osaka-shi/O=\"Example Inc\"/OU=Foo/CN=localhost"
6. 証明書に付加する SAN (Subject Alternative Name サブジェクト代替名) を入れたテキストファイルを作成
このコマンドは、localhost.csx
というファイルを作成し、そのファイルに**Subject Alternative Name (SAN)**情報を書き込みます。SAN情報は、HTTPS接続時にサーバの証明書とホスト名の照合に使用されます。
$ echo 'subjectAltName = DNS:localhost, DNS:localhost.localdomain, IP:127.0.0.1, DNS:app, DNS:app.localdomain' > localhost.csx
7. CSRにSAN情報も付加し、CA秘密鍵とCA証明書とで署名してサーバー証明書を作成
このコマンドは、localhost.csr
という証明書署名要求(CSR)ファイルとlocalhost.csx
というSAN情報ファイルを使用して、localhost.crt
というHTTPSサーバ証明書を作成します。
$ openssl x509 -req -days 1825 -CA localCA.crt -CAkey localCA.key -CAcreateserial -in localhost.csr -extfile localhost.csx -out localhost.crt
補足:作成されたファイル
$ ll
total 30
-rw-r--r-- 1 user 197609 1232 Mar 20 06:20 localCA.crt
-rw-r--r-- 1 user 197609 1018 Mar 20 06:20 localCA.csr
-rw-r--r-- 1 user 197609 1732 Mar 20 06:20 localCA.key
-rw-r--r-- 1 user 197609 42 Mar 20 06:20 localCA.srl
-rw-r--r-- 1 user 197609 1596 Mar 20 06:20 localhost.crt
-rw-r--r-- 1 user 197609 1026 Mar 20 06:20 localhost.csr
-rw-r--r-- 1 user 197609 102 Mar 20 06:20 localhost.csx
-rw-r--r-- 1 user 197609 1732 Mar 20 06:20 localhost.key
8. CA証明書をクライアントにインストール
Windwosの場合
- Windowsキーを押して、
certlm.msc
を実行 - 信頼されたルート証明機関に
localCA.crt
をインポート
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F482880%2F7c09c7b1-37e4-cb32-2f6c-fac3fcba02c2.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=7ab327fb5d41005646fa95632d2c223b)
ウィザードにしたがって信頼されたルート証明機関にインポートする
9. サーバー側で秘密鍵とサーバー証明書を指定して起動
サーバー側の設定例
Node.js での実装例
const https = require('https');
const fs = require('fs');
const port = 8443;
const options = {
key: fs.readFileSync('ssl/localhost.crt'),
cert: fs.readFileSync('ssl/localhost.key')
};
https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('hello world\n');
}).listen(port);
Go での実装例
package main
import "github.com/gin-gonic/gin"
func main() {
router := gin.Default()
router.GET("/", func(c *gin.Context) {
c.HTML(200, "index.html", nil)
})
router.RunTLS(":8443", "ssl/localhost.crt", "ssl/localhost.key")
}
TLSハンドシェイクが成功すれば、下記の画像のようにhttps
が表示されます