双方向TLS
普通のTLSのこと聞いたはずでしょう?内部のクライアントに限りとしたいなら、両方のTLSやってみます
Published onUpdated on
8 min read
ウェブ開発をしたことがある人はきっと、TLSという略語を聞いたはずでしょう。TLSは「Transport Layer Security」の略で、OSIの第4段のレイヤの接続を暗号化して安全に行うためのものであります。HTTPとHTTPSの違いも知っているでしょう。HTTPは昔から、ウェブの初期の形です。現在に誰でも知っている大発明「WorldWideWeb」を発明したティム・バーナーズ・リー氏が、こう述べています。
我々は、美しく複雑なグラフィックよりも、一般性と互換性を重視にして、世界的な接続システムを目指すべきのだ。誰も必要な参照や情報を見つけられ、再び必要な時になったときも容易に探せる環境を作ることを目標とする。
HTTPだけでは安全に通信することができません。その理由で、人間がHTTPの直上に新たなプロトコルを発明しまして、Secured(安全)のSがHTTPに後付きました。HTTPSのプロトコルを使えば、安全にパスワードやセンシティブな情報などを通信することができるとなります。これは「SSL」と呼ばれます。「あれ、さっきからTLSの話じゃなかった?」と疑問に思う方がいるんでしょう。SSLはTLSの双子のように、HTTPSの際にならいつも同時に起動しているものです。SSLはただ、あなたとサーバーの通信が盗聴したりすることができないということです。TLSは少しより複雑で、サーバーの本体とかサーバーは自分の正体について事実を述べているのかとかをチェックするプロトコルです。
普通のTLSのなら、あなたが繋がり次第、サーバーが自分の証明書とキーを捧げ、あなたのデバイスがその情報でチェックしてくれます。合わなければ、あなたに報告するようにします。見たことがありますか?「このウェブサイトは不完全であり、サーバーまでの接続が自動的に切りました。」という通知が出てきましたか?サーバーから受けた認証とキーがおかしくて合わないのでです。じゃ、双方向TLSは同じプロトコルです。しかし、サーバーからだけではなく、あなたから認証と認証キーも送らなければならないことです。つまり、双方向の名通り、クライアント(あなたのこと)もサーバーも証明書で認証し合う仕組みであります。
今(書く時)私は大学生四年生であり、卒業も近づいています。この話題について授業を受けたことをきっかけに、Goというプログラミング言語を学び始めました。「アドバンスウェブ開発」という名です。
学生のポータルによれば、このコースは二つのクラスが開けられています。月曜午後のクラスではReactを教えると聞きましたけど、午前の方ではReactよりもウェブの概念を中心に教えるようです。私は幾つかReactプロジェクトができたことがあり、その上にReact自体が本当に好きではないので、午後のクラスを避けるにしました。
この記事もそのクラスからの内容です。今週の宿題は「APIの安全性を調べ、以下の三つのケースに対して解決を捧げよう」というものです。
- 会社や施設など以内にだけがアクセス権利がある。
- 少ないの外部のクライアントがアクセスできる。
- インターネットに誰でもいつでも登録できてすぐにアクセスできる。
2番は想定通り、APIトークンを利用します。3番は標準的なJWTに決定しました。残るの1番をよく調べて、あらゆるのAIを聞いたら、mTLSのことが出てきました。
通常、TLS認証には信用できるCA(認証局と呼べ、英 Certificate Authority)から署名をもらうのです。しかし、クラスの皆さんの前にプレゼントできるため、Self-signed(自分がCAとして認証書を作ること)しかないでしょう。Windowsでは使わないので詳しくないですが、LinuxやmacOSを使っている方は、opensslというコマンド(またはパッケージ、キャスク)をインストールすればすぐに自分のCAを作成することができます。以下のスクリプトには、各コマンドをコメント説明しています。
#!/bin/sh
# 注意!このスクリプトはプロダクション環境には絶対に使うな!!
# テストや学習で作られたものであり、安全性が非常に低いです。
# 安全な認証書を作成したいのなら、信用できるグロバル認証局(例 Digicert)から署名を取得すべきです。
# エラーが発生したら、すぐにエラーコードでやめます。
set -e
# 先ずは、ルートCAのキーと認証書を作ります。
# -nodesというオプションは「パスワードを使わない」という意味です。
# キーはランダムアルゴリズムで作成し、そのキーから認証書を発行します。
openssl genrsa -out ./certs/ca.key 4096
openssl req -x509 -new -nodes -key ./certs/ca.key -sha256 -days 3650 -out ./certs/ca.crt \
-subj "/C=VN/ST=HCMC/L=HCMC/O=WNC/OU=NNDK/CN=WNC Root CA"
# これから、全て同じです。サーバーもクライエントも基本は同じです。
# 異なることはCN(別名、英 Common Name)だけです。この名によって、誰のものだと区別できます。
openssl genrsa -out ./certs/server.key 2048
openssl req -new -key ./certs/server.key -out ./certs/server.csr \
-subj "/C=VN/ST=HCMC/L=HCMC/O=WNC/OU=NNDK/CN=Sakila"
openssl x509 -req -in ./certs/server.csr -CA ./certs/ca.crt -CAkey ./certs/ca.key \
-CAcreateserial -out ./certs/server.crt -days 365 -sha256
openssl genrsa -out ./certs/client1.key 2048
openssl req -new -key ./certs/client1.key -out ./certs/client1.csr \
-subj "/C=VN/ST=HCMC/L=HCMC/O=WNC/OU=App/CN=Client 1"
openssl x509 -req -in ./certs/client1.csr -CA ./certs/ca.crt -CAkey ./certs/ca.key \
-CAcreateserial -out ./certs/client1.crt -days 365 -sha256
openssl genrsa -out ./certs/client2.key 2048
openssl req -new -key ./certs/client2.key -out ./certs/client2.csr \
-subj "/C=VN/ST=HCMC/L=HCMC/O=WNC/OU=App/CN=Client 2"
openssl x509 -req -in ./certs/client2.csr -CA ./certs/ca.crt -CAkey ./certs/ca.key \
-CAcreateserial -out ./certs/client2.crt -days 365 -sha256