Labee Dev Toolbox
技術ノートガイド用語解説
無料で試す
  1. ホーム
  2. / 用語解説
  3. / 証明書ピンニング(Certificate Pinning)
SSL

証明書ピンニング(Certificate Pinning)

2026年5月12日 更新

概要

証明書ピンニング(Certificate Pinning) は、クライアントが接続先サーバーの証明書または公開鍵を事前に記録(ピン留め)し、接続時に提示された証明書がピン留めされたものと一致するかを検証する技術です。一致しない場合、たとえ正規の CA から発行された証明書であっても接続を拒否します。

ピンニングが解決する問題は、PKI のトラストモデルの構造的な弱点です。ブラウザーのトラストストアには数百の CA が含まれており、どの CA でも任意のドメインに対して証明書を発行できます。2011 年の DigiNotar 事件では、侵害された CA が google.com の不正証明書を発行しました。ピンニングを使えば、ドメインオーナーが信頼する特定の CA または特定の公開鍵だけを受け入れるように制限できます。

ピンニングの実装方式には複数のバリエーションがあります。ブラウザー向けの HTTP Public Key Pinning(HPKP)は RFC 7469(2015 年)で標準化されましたが、運用リスクの高さから Chrome が 2018 年に廃止し、他のブラウザーも追随しました。現在ピンニングが使われるのは、主にモバイルアプリとデスクトップアプリケーションです。

仕組み

ピンニングには対象の粒度や配信方法が異なる複数の方式があり、用途に応じて使い分けます。

ピンニングの対象

ピンニングの対象は大きく 3 つに分類できます。

証明書ピンニングは、サーバー証明書全体をピン留めします。証明書が更新されるとピンが無効になるため、証明書の更新のたびにアプリのアップデートが必要です。

公開鍵ピンニングは、証明書内の公開鍵(SubjectPublicKeyInfo)をピン留めします。証明書を更新しても同じ鍵ペアを使えばピンは有効なままです。ただし鍵漏洩時には鍵の変更が必要になり、ピンの更新も必要です。

CA ピンニングは、中間 CA またはルート CA の公開鍵をピン留めします。その CA が発行した証明書であれば受け入れるため、柔軟性が高い反面、ピンニングの粒度は粗くなります。

HPKP(HTTP Public Key Pinning)の歴史

RFC 7469 で標準化された HPKP は、HTTP レスポンスヘッダーで公開鍵のハッシュを配信する方式でした。

Public-Key-Pins: pin-sha256="base64=="; pin-sha256="backup-base64=="; max-age=5184000

HPKP のヘッダーには最低 2 つのピンが必要でした。1 つは現在の鍵、もう 1 つはバックアップ用の鍵です。max-age でピンの有効期間を指定します。

HPKP が廃止された理由は次のとおりです。

設定ミスのリスクが極めて高いことが最大の理由です。誤ったピンを長い max-age で配信した場合、そのドメインへのアクセスが max-age の期間中完全に不能になります(自殺ピンニング)。バックアップ鍵を紛失した場合も同様です。

攻撃者が HPKP を悪用して、侵害したサイトに自分の鍵のピンを設定し、正規の管理者がドメインを取り戻しても接続をブロックし続ける「ランサムピンニング」攻撃も理論的に可能でした。

Chrome は 2018 年 5 月の Chrome 67 で HPKP のサポートを廃止しました。Firefox も 2019 年に廃止しています。RFC 7469 の後継は作成されていません。代替として Certificate Transparency が推奨されています。

モバイルアプリでのピンニング

HPKP の廃止後も、モバイルアプリでは証明書ピンニングが広く使われています。アプリのコード内に信頼する公開鍵のハッシュをハードコーディングし、TLS 接続時にサーバー証明書と照合します。

Android では network_security_config.xml でピンニングを宣言的に設定できます。

<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">api.example.com</domain>
        <pin-set expiration="2027-01-01">
            <pin digest="SHA-256">base64EncodedPinHash==</pin>
            <pin digest="SHA-256">backupBase64EncodedPinHash==</pin>
        </pin-set>
    </domain-config>
</network-security-config>

iOS では NSAppTransportSecurity の設定やコードレベルでの URLSessionDelegate 実装でピンニングを行います。

ブラウザーのビルトインピン

Chrome は HPKP を廃止しましたが、Google 自身のドメイン(google.com、youtube.com など)に対するビルトインピンは引き続き維持しています。これらのピンはブラウザーのソースコードにハードコーディングされており、HTTP ヘッダーではなくバイナリ更新で管理されます。

設定例

ピンニング用の公開鍵ハッシュ取得と、curl による接続テストの手順を示します。

OpenSSL で公開鍵のハッシュを取得

ピンニング用の公開鍵ハッシュを取得するには次のコマンドを使います。

openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -pubkey -noout | openssl pkey -pubin -outform DER | openssl dgst -sha256 -binary | openssl enc -base64
YZPgTZ+woNCCCIW3LH2CxQeLzB/1m42QcCTBSdgayjs=

この Base64 エンコードされたハッシュ値をピンとして使用します。

curl でピンニングを使った接続テスト

curl --pinnedpubkey "sha256//YZPgTZ+woNCCCIW3LH2CxQeLzB/1m42QcCTBSdgayjs=" https://example.com

--pinnedpubkey オプションにピンを指定すると、curl はサーバーの公開鍵がピンと一致しない場合に接続を拒否します。

確認方法

openssl でサーバー証明書の公開鍵ハッシュを取得して、アプリに設定されたピンと一致するか確認します。

openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -pubkey -noout | openssl pkey -pubin -outform DER | openssl dgst -sha256 -binary | openssl enc -base64

中間証明書のハッシュも同様に取得できます。

openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null 2>/dev/null | openssl x509 -pubkey -noout | openssl pkey -pubin -outform DER | openssl dgst -sha256 -binary | openssl enc -base64

外部の視点からも確認したい場合は、Labee Dev Toolbox の SSL Cert API を使うと、外部の視点から見た結果を取得できます。

curl "https://labee.dev/api/ssl-cert?hostname=example.com"
{
  "success": true,
  "data": {
    "hostname": "example.com",
    "port": 443,
    "reachable": true,
    "status": 200
  },
  "error": null,
  "meta": { "responseTime": 123 }
}

data.reachable が true であれば HTTPS 接続が成立しています。ピンニングの検証はクライアント側で行われるため、この API ではピンニングの成否は判定できませんが、サーバーの証明書が有効であることの基本確認として使えます。

よくある問題

ピンニングは証明書や鍵の更新時にアプリの接続障害を引き起こすリスクが高く、運用設計が重要です。

証明書更新時にアプリが接続不能になる

証明書ピンニング(証明書全体のピン留め)を使っている場合、サーバー証明書を更新するとピンが一致しなくなり、アプリが接続を拒否します。公開鍵ピンニングを使い、証明書更新時に同じ鍵ペアを再利用することで回避できます。ただし、バックアップピンの設定が必須です。鍵漏洩で鍵を変更する事態に備えて、バックアップ鍵のピンをあらかじめ設定しておきます。

CA の中間証明書変更でアプリが接続不能になる

CA ピンニングを使っている場合、CA が中間証明書を変更するとピンが一致しなくなります。Let’s Encrypt は 2024 年に中間証明書を R3 から R10/R11 に切り替えました。中間 CA のピンを使っていたアプリはこの切り替えで影響を受けました。CA ピンニングを使う場合は、CA の中間証明書の更新予定を把握しておく必要があります。

ピンニングがデバッグやセキュリティ監査を妨げる

企業ネットワークでは、TLS インスペクション(中間者プロキシ)を使って通信内容を検査することがあります。ピンニングが設定されたアプリはプロキシの証明書を拒否するため、通信の検査ができません。Android 7.0 以降ではデバッグビルドでのみカスタム CA を信頼する設定が可能です。

アプリの強制アップデートが必要になるリスク

ピンの更新にはアプリのアップデートが必要です。ユーザーがアップデートしなければ、古いピンのまま接続を試み続けます。ピンの有効期限(expiration)を設定し、期限切れ後はピンニングを無効化するフォールバックを設計に含めておきます。

実際のドメインで確認してみる

登録不要、無料です。ドメイン名を入れるだけで外部からの見え方を確認できます。

無料で試す

関連用語

SSL

SSL/TLS 証明書

ウェブサイトの通信を暗号化し、サーバーの身元を証明するデジタル証明書。HTTPS 配信の前提条件。

SSL

証明書チェーン(Certificate Chain)

サーバー証明書からルート認証局までの信頼の連鎖を構成する証明書群。チェーンの不備は SSL エラーの主な原因。

SSL

証明書透明性(Certificate Transparency)

CA が発行した証明書をパブリックログに記録し、不正発行を検知可能にする仕組み。Chrome は CT ログ未登録の証明書を拒否する。

SSL

HSTS(HTTP Strict Transport Security)

ブラウザーに HTTPS 接続を強制するセキュリティポリシー。HTTP へのアクセスを自動的に HTTPS へアップグレードします。

SSL

ルート認証局(Root CA)

PKI の信頼の起点となる最上位の認証局。OS やブラウザーのトラストストアに格納されている。

コンテンツ 技術ノート ガイド 用語解説
ツール ツール一覧 API Reference
Labee 日本語トップ Labee LLC
© 2026 Labee LLC . All rights reserved.
ホーム ブログ ガイド 用語集