← 記事一覧

テクノロジー

SSL/TLS入門 | mTLS とは?クライアント証明書による相互認証の仕組み

はじめに

前回の記事では、サーバ証明書がどのように発行されるのか、ブラウザがCA・証明書チェーン・PKIを使ってサーバ証明書を検証する仕組みを整理しました。

通常のHTTPS通信では、ブラウザ等のクライアント側がサーバ証明書を検証することで、

接続先の相手は本当に正しいサーバなのか?

を確認します。

逆に、Webサーバ側が「接続しに来ているクライアントは信頼できるのか?」を証明書を使って検証する方法があります。

それを実現するのが、mTLS (Mutual TLS / 相互TLS)です。

今回は、mTLSについて整理します。

mTLSとは

通常のTLSでは、サーバだけがサーバ証明書を提示してクライアントがそれを検証します。

mTLSでは、クライアントもクライアント証明書を提示します。

通常のTLS

mTLS

このように、両方をTLSレイヤーで認証するのがmTLSです。

クライアント証明書とは

クライアント証明書も、基本的な構造はサーバ証明書と同じです。

クライアントは、

  • クライアント秘密鍵
  • クライアント公開鍵

という鍵ペアを持っています。

そして、クライアント公開鍵を含む証明書をCAに発行してもらいます。

クライアント証明書

Subject
    クライアントの識別情報

Public Key
    クライアント公開鍵

Issuer
    証明書を発行したCA

Validity
    有効期間

Signature
    CAによる署名

サーバ証明書では、

この公開鍵はexample.comのもの

を認証していました。

クライアント証明書では、証明書に含まれる識別情報や公開鍵を利用して、

この公開鍵を持つクライアントは、信頼するCAによって認証されている

ことをサーバ側が確認します。

mTLSでは誰がCAを信頼するのか

通常のTLSでは、クライアント側が信頼するCA (TrustStore)を持っています。(TrustStoreについては過去記事をご覧下さい)

一方mTLSでは、サーバ側にも「どのCAが発行したクライアント証明書を信頼するのか」という設定が必要になります。

例えば、自社専用のCAを用意して、

自社Client CA
      │
      ├── クライアント証明書A
      │
      ├── クライアント証明書B
      │
      └── クライアント証明書C

というクライアント証明書を発行しておきます。

サーバ側では、

自社クライアントCAによって発行されたクライアント証明書だけを信頼する

という設定ができます。

これによって、証明書を持っていないクライアントや、信頼していないCAから発行された証明書を持つクライアントからの接続を拒否できます。

証明書をコピーすればなりすませるのでは?

ここで疑問があります。

クライアント証明書をサーバへ送るだけなら、

他人のクライアント証明書をコピーして送れば、なりすませるのでは?

と思えます。

しかし、クライアント証明書だけではmTLS認証は成立しません。

クライアントは、その証明書に含まれる公開鍵の秘密鍵を持っていることも証明する必要があります。

ここで登場するのが、TLSのCertificateVerifyです。

CertificateVerify

mTLSのTLSハンドシェイクでは、クライアントはクライアント証明書を送った後、クライアントの公開鍵に対応する秘密鍵を使ってハンドシェイクの内容に対する署名を作成し送信します。

サーバはクライアント証明書に含まれる公開鍵を使って、CertificateVerifyの署名を検証します。

検証に成功すれば、

このクライアントは、提示したクライアント証明書に対応する秘密鍵を持っている

ことを確認できます。

つまりmTLSでは大きく、

  • 信頼できるCAから発行された証明書か?
  • 証明書に対応する秘密鍵を持っているか?

という2つの観点でクライアントを認証します。

mTLSのTLSハンドシェイク

TLS1.3のmTLSハンドシェイク全体のフローは以下になります。

通常のTLSと大きく違うのは、サーバからCertificateRequestが送られる点です。

これは、クライアント証明書の提示を要求するリクエストで、クライアントはそれに対し

  • Certificate
  • CertificateVerify

を送ります。

これによってサーバ側もクライアントを認証できます。

mTLSのユースケース

mTLSは、一般的なWebサイトのTLS化ではなく、以下のようなシステム同士の通信で使われることが多いです。

  • API同士の認証
  • マイクロサービス間 (サービス間)の通信
    • Kubernetesなどのコンテナ間 (システム内)での認証。不正なコンテナが紛れ込んでも通信を拒否できる。
  • IoTデバイス
    • IoTデバイスがサーバに接続する際、IoTデバイスにクライアント証明書を持たせるとなりすましを防げる。
  • ゼロトラスト環境
    • 社内ネットワークであっても互いを信頼しないような、高度なセキュリティ環境でmTLSは使われことがある。

ID・パスワードやAPIキーを送るのではなく、TLS接続そのものの段階でクライアントを認証できるのが特徴です。

おわりに

今回はmTLSについて、通常のTLSとの違いからクライアント証明書、CertificateVerifyによる秘密鍵の所持証明まで整理しました。

通常のTLSでは、

クライアントがサーバを認証する

のに対して、mTLSでは、

クライアントがサーバを認証し、サーバもクライアントを認証する

という双方向の認証を行います。

前回調べたCA・PKI・証明書チェーンの仕組みは、サーバ証明書だけのものではありません。

クライアント側にも秘密鍵・公開鍵・証明書を持たせることで、同じPKIの仕組みをクライアント認証にも利用できます。

ユースケースとして、API間の認証などシステム間認証に用いられることを確認できました。

次回の記事では、実際にローカルでmTLSを実装してみようと思います。