証明書ピンニングとは?

証明書ピンニングとは、SSL/TLS(正確には TLS)通信において、信頼できる証明書や公開鍵のみをアプリケーション側で明示的に指定(ピン留め)する仕組みです。中間者攻撃(MITM:Man-in-the-Middle)や証明書の偽装による攻撃を防ぐことが目的です。

かつては「HTTP公開鍵ピンニング(HPKP:HTTP Public Key Pinning)」と呼ばれる仕組みがブラウザ(ChromeやFirefoxなど)でサポートされていましたが、運用上の手間や誤設定による通信遮断などのリスクが大きく、現在ではサポートを終了しています

しかし、モバイルアプリやデスクトップアプリでは現在も広く利用されている手法です。

本記事では、この証明書ピンニングについて、基本と仕組みを解説します。

なぜ証明書ピンニングが必要なのか?

証明書ピンニングが有効なのは、中間者攻撃(MITM)による通信の盗聴や改ざんのリスクを軽減するためです。

中間者攻撃とは、通信の途中に割り込んで、通信内容を盗聴・改ざんする攻撃手法です。

実際に発生した事例

これらは、正規に見える証明書であっても認証局が不正に証明書を発行してしまった例です。このような場合、証明書ピンニングが有効に働きます。

証明書ピンニングでは、特定のドメインに対して指定した証明書(または公開鍵)を使用(ピン留め)することで、不正な証明書が提示された際に通信を拒否することが可能になります。

証明書ピンニングの仕組みを知ろう

SSL/TLS通信では、通信先のサーバーは証明書(公開鍵付き)をクライアントに提示します。

この証明書は認証局(CA)による署名付きであり、クライアントはその署名を検証して「このサーバーは信頼できる」と判断します。暗号化通信は、公開鍵で暗号化し、秘密鍵で復号する仕組みです。

しかしこの仕組みでは、クライアントが信頼している認証局であれば、そのCAが発行した証明書はすべて受け入れられてしまいます。仮に悪意のあるCAや誤って証明書を発行したCAがあっても、クライアントはそれを信頼してしまうのです。

そこで登場するのが証明書ピンニングです。証明書ピンニングでは、アプリケーション側で明示的に信頼する証明書や公開鍵のハッシュを指定します。これにより、CAが不正な証明書を発行しても、それがピン留めされた情報と一致しなければ通信は拒否されます。

なお、HPKPのようにサーバーが Public-Key-Pins ヘッダーを返してクライアントにピン留めを指示する方式も存在しましたが、現在では主なブラウザで非推奨・廃止されており、モバイルやデスクトップアプリではアプリ側で静的にピン留めする方式が主流です。

参考までに、かつてのHPKPの記述例は以下の通りです。

Public-Key-Pins: pin-sha256="base64=="; max-age=expireTime; includeSubDomains; report-uri="https://example.com/report"
Public-Key-Pins-Report-Only: pin-sha256="base64=="; max-age=expireTime; includeSubDomains; report-uri="https://example.com/report"

証明書ピンニングを行っているアプリ

証明書ピンニングを行っているアプリの例

証明書のピン留めとSSLインスペクション | Zscaler によると、以下のような企業・サービスのモバイル/デスクトップアプリが証明書ピンニングを行っているとされています:

  • Adobe
  • Amazon
  • Google
  • Apple
  • Microsoft
  • X(旧Twitter)
  • Instagram

こうした大手サービスでは、セキュリティ強化のため証明書ピンニングが広く採用されています。

証明書ピンニングを導入する際の注意点

証明書ピンニングは強力なセキュリティ対策ですが、適切に運用されないと逆に障害を引き起こすリスクもあります

運用が複雑になる

証明書の更新や、認証局を変更する場合、ピン留め情報も更新する必要があります。特にモバイルアプリではアプリの更新が必要になるため、運用の手間が増えます。

誤設定のリスク

ピン情報(公開鍵のハッシュなど)を誤って設定すると、正規の証明書でも接続できず通信が失敗する可能性があります。復旧にはアプリの再配布が必要になることもあるため、十分なテストとバックアップピンの設定が推奨されます。

開発・テスト時の運用方法

SSL/TLS証明書であればサーバーに設定して終わりですが、証明書ピンニングではクライアント(アプリ)側でも設定が必要です。

開発・テスト環境では本番とは異なる証明書を使うことも多く、環境ごとにピン留め対象を変更できる仕組みやビルドフローを準備しておくことが重要です。

まとめ

今回は、アプリの通信をよりセキュアにするための「証明書ピンニング」について解説しました。

証明書ピンニングは、TLS通信において信頼できる証明書や公開鍵のみをアプリ側で明示的に指定することで、不正な証明書による中間者攻撃を防ぐ仕組みです。

一方で、運用が複雑になる・更新ミスで通信不能になるといったリスクもあります。導入にあたっては、アプリのセキュリティと運用負荷のバランスを考慮し、更新フローやテスト体制を整備しておくことが重要です