パスキーの仕組みをSSH鍵認証と比べてみる

  • パスキーはSSHの公開鍵認証と同じ仕組みで、秘密鍵をデバイス内に保管し、サービスには公開鍵だけを渡す。
  • ログイン時は秘密鍵で署名したデータだけをやり取りするため、認証情報がネットワークを流れない。
  • 秘密鍵はセキュアエレメントという専用チップに格納され、OSからもアクセスできないためコピーや漏洩が起きない。
  • 登録時に鍵生成から公開鍵の送信まで自動で完了し、クラウドバックアップやクロスデバイス認証にも対応している。

関連記事

1. パスキーと印鑑

パスキーを登録するとき、何をしているのかピンとこない人は多いと思います。
「パスワードを登録するのと何が違うの?」という感覚です。

パスキーの仕組み — SSH鍵認証から考える パスワード(暗証番号) パスキー(銀行印) あなた 暗証番号 “1234” 送信 銀行 暗証番号 “1234” 保管 ⚠ 漏洩するとそのまま悪用される 合言葉方式 あなた 印鑑 手元に保管 押す 銀行 印影のみ 登録・照合 印鑑がなければ偽造できない 署名検証方式 vs パスワード = 暗証番号(両者が秘密を共有) パスキー  = 銀行印(本物は手元だけ) 大事な取引に銀行印が使われるのは、偽装しにくいから

銀行口座の暗証番号と銀行印を例に考えると、パスキーの役割が整理しやすくなります。

【パスワード(暗証番号方式)】
  あなた               銀行
  ────               ────
  暗証番号 "1234" ──→ 暗証番号 "1234" を保管
                       ↑
                       漏洩するとそのまま悪用される

【パスキー(銀行印方式)】
  あなた               銀行
  ────               ────
  印鑑(手元に保管)    印影(登録済み)を保管
     ↓ 押す
  印影 ────────────→ 印影を照合
                       ↑
                       印影が漏れても印鑑がなければ偽造できないCode language: JavaScript (javascript)

キャッシュカードを作るとき、暗証番号を設定します。
暗証番号は銀行側のシステムにも記録されていて、ATMで番号を入力すると銀行側の記録と照合して本人確認します。
合言葉を両者が知っているから成立する、合言葉方式です。

一方、銀行印は違います。
銀行に登録するのは印影だけで、印鑑そのものは手元に置きます。
窓口で手続きするときは印鑑を押し、銀行が登録済みの印影と照合します。
銀行は印影しか持っていないので、印影が漏れても印鑑がなければ偽造できません。
これは、署名検証方式と呼ばれます。

パスワードは暗証番号、パスキーは銀行印に相当します。
大事な取引では銀行印の方が使われるのは、偽装しにくいからです1
パスキーも同様で、アカウントのなりすまし対策として導入されました。

1.1. SSH公開鍵認証という先行技術

エンジニアは、パスワード認証だけでなく、この「銀行印」のやり方を以前から使っています。
それが、SSHの公開鍵認証です。

SSH公開鍵認証という先行技術 クライアント サーバー 公開鍵を送信 チャレンジ(乱数) 署名データを送信 秘密鍵で署名 受信 公開鍵で検証 接続許可 秘密鍵はネットワークを流れない 公開鍵=印影 秘密鍵=印鑑

たとえば、ホームページを管理するためにレンタルサーバーにログインするとき、パスワードでログインする方法もありますが、多くのサービスが鍵認証を推奨しています。

そのときに使うのが SSH です。
SSHはSecure Shellの略で、ネットワーク越しに別のコンピュータを操作する仕組みで、サーバーへのログインに使います。
パスワード認証もできますが、公開鍵認証の方が安全です。

【SSH公開鍵認証の登録】
  クライアント(手元のPC)        サーバー
  ────────────────            ────────
  ssh-keygen
    → 秘密鍵 ~/.ssh/id_ed25519   (手元に保管)
    → 公開鍵 ~/.ssh/id_ed25519.pub

  ssh-copy-id ─── 公開鍵 ──────→ ~/.ssh/authorized_keys に追記

【SSH公開鍵認証のログイン】
  クライアント                    サーバー
  ────────                      ────────
                ←── チャレンジ(乱数)────
  秘密鍵で署名
                ──── 署名 ──────────→  公開鍵で検証 → 接続許可
  (秘密鍵はネットワークを流れない)Code language: JavaScript (javascript)

公開鍵認証の準備は、ターミナルで次のコマンドを実行するところから始まります。

ssh-keygen -t ed25519Code language: Bash (bash)

このコマンドは、2つのファイルを作成します。
~/.ssh/id_ed25519 が秘密鍵、~/.ssh/id_ed25519.pub が公開鍵です2
鍵はテキストデータなので、ファイルを開けば中身を確認できます。
秘密鍵は手元に保管し、公開鍵を接続先のサーバーに送ります。

ssh-copy-id user@192.168.1.23Code language: Bash (bash)

このコマンドで、公開鍵の内容がサーバーの ~/.ssh/authorized_keys に追記されます。

接続時、手元のPCは秘密鍵で「署名」というデータを作ってサーバーに送ります。
サーバーは登録済みの公開鍵で署名を検証し、通れば接続を許可します3

銀行印の比喩で言えば、公開鍵が印影、秘密鍵が印鑑です。
サーバーには印影しか渡していません。
つまり、パスワードと違って、インターネット上を流れるデータには認証情報が含まれないため、通信を盗聴されてもログインには使えません。

反対に、最大のリスクはパソコン自体に侵入されることです。
秘密鍵がファイルとして存在する以上、OSやアプリが侵害されれば秘密鍵を読み取られる可能性があります。

2. パスキーも同じ構造

パスキーは、この公開鍵認証をWebサービスのログインに応用した仕組みです。

パスキーも同じ構造 SSH パスキー ssh-keygen 登録ボタンで自動生成 authorized_keysへ登録 公開鍵をサービスへ送信 ファイルに秘密鍵保管 セキュアエレメントに保管 秘密鍵で署名 → 検証 秘密鍵で署名 → 検証 生体認証は「秘密鍵のロック解除」 生体情報はサービス側に送られない

「パスキーを登録する」とは、公開鍵をサービスに渡す行為です。
パスワードを登録するのと似て見えますが、どちらかというとSSHの ssh-copy-id に近いです。

「パスキーを登録する」ボタンを押して生体認証をしたとき、裏側では3つの処理が一気に完了します。
鍵ペアの生成、公開鍵のサービスへの送信、秘密鍵のデバイス内への保管です。
SSHの準備では、手動のコマンドでやっていた操作が自動的に進むのです。

SSHの操作パスキーの対応
ssh-keygen で鍵ペア生成登録ボタンを押した瞬間に自動生成
authorized_keys に公開鍵を登録サービス側に公開鍵を送信
~/.ssh/id_ed25519 に秘密鍵を保管セキュアエレメントに秘密鍵を書き込み
接続時に秘密鍵で署名ログイン時に秘密鍵で署名
サーバーが公開鍵で検証サービスが公開鍵で検証
【パスキーの登録】
  デバイス(iPhone等)             Webサービス
  ────────────────             ──────────
  「登録する」ボタン → 生体認証
  セキュアエレメント内で鍵ペア生成
    → 秘密鍵(セキュアエレメントに保管)
    → 公開鍵 ────────────────→ サービス側に保存

【パスキーのログイン】
  デバイス                         Webサービス
  ────────                       ──────────
                  ←── チャレンジ(乱数)────
  生体認証
  セキュアエレメント内で署名
                  ──── 署名 ──────────→ 公開鍵で検証 → ログイン完了
  (秘密鍵はデバイスから出ない)

ここで生体認証の意味を整理しておきます。
生体認証がパスキーの「鍵」本体になっているわけではありません。

これは、秘密鍵を取り出すためのロック解除で、SSH秘密鍵のパスフレーズに相当します。
つまり、生体情報はサービス側には送られません4

2.1. 見えないことが設計の意図

それでは、SSHのような秘密鍵のファイルはどうやって確認するのでしょう。
これは、取り出せない場所に書き込まれています。

見えないことが設計の意図 SSH 秘密鍵 ファイルシステム ~/.ssh/id_ed25519 コピー可・漏洩リスク パスキー 秘密鍵 OS・アプリ層(アクセス不可) セキュアエレメント 秘密鍵(取り出せない) 署名処理はここで完結 vs ドメインに紐付き → フィッシングサイトでは使えない OSが侵害されても秘密鍵には触れられない 削除はできるが、コピーして移すことは不可 再登録が必要(印鑑の作り直しと同じ)
【SSHの秘密鍵】
  ファイルシステム
  └── ~/.ssh/id_ed25519   ← コピーできる、漏洩リスクがある

【パスキーの秘密鍵】
  デバイス
  ├── OS・アプリ層
  │     ↕ アクセス不可
  └── セキュアエレメント(Secure Enclave)
        └── 秘密鍵               ← 取り出せない
              ↓ 署名処理はここで完結
              署名データだけが外に出るCode language: JavaScript (javascript)

パスキーの秘密鍵は、「セキュアエレメント」という専用チップに保管されます。
SDカードやSSDではなく、iPhoneやAndroidに内蔵された独立したチップで、OSからも直接アクセスできない設計です5
秘密鍵を使った署名処理はチップの内部で完結し、秘密鍵そのものが外に出ることはありません。

SSHの秘密鍵の場合は、ストレージにファイルとして存在するので、コピーも移動も、そして漏洩も起こります。
一方、パスキーの秘密鍵はコピーできず、漏洩もしません。

SSHで残っていた「PCへの侵入」というリスクは、セキュアエレメントの設計で対応しています。
秘密鍵がOSから隔離されたチップに保管されているため、OSやアプリが侵害されても秘密鍵には触れられません。

パスキーそのものをファイルとして取り出すことはできませんが、iCloudキーチェーンやGoogleパスワードマネージャーなどのアプリからは、保存されているパスキーを確認して削除することができます。
削除はできてもコピーして移すことはできないので、別のデバイスで使いたい場合や作り直したい場合は、サービス側でパスキーを削除してから改めて登録し直します。
印鑑を紛失したときに同じ印影では作り直さず、新しい印鑑を登録し直すのと同じ発想です。

つまり、パスキーは実体が見えないためにわかりにくいですが、それは安全のために見えない設計になっているのです。

2.2. パスキーがSSHより進んでいる点

そのほか、パスキーにはフィッシング対策の工夫があります。

それは、パスキーはオリジンと呼ばれるURLのドメインに紐付いて生成されること。
example.com のパスキーは example-fake.com では使えません6
偽サイトに誘導されても、パスキーが応答しないのです。

3. パスキーとクラウド保存

鍵の管理面では、SSHの鍵は自分で生成し、自分でサーバーに送り、自分でバックアップします。

クラウド保存とクロスデバイス認証 PC / ブラウザ iPhone iCloud / Google PM QRコード表示 署名データを返送 生体認証 → 署名 秘密鍵はiPhoneから出ない 機種変更してもクラウドから復元 iCloudキーチェーン / Googleパスワードマネージャー

このパスキーは、暗号化してクラウドにバックアップを保存しておくことができます。
そうしておけば、iPhoneを機種変更しても、iCloudから復元されます7

iCloudキーチェーンやGoogleパスワードマネージャーは、二段階認証やログイン通知が充実しているため、パスキーの保存先として安全性が高いです。
パスキーはサービスごとに鍵ペアが自動生成され、iCloudキーチェーンやGoogleパスワードマネージャーに自動保存されます。

3.1. クロスデバイス認証

PCのブラウザでスマートフォンに保存したパスキーを使うことができます。
これを、クロスデバイス認証といいます。

【クロスデバイス認証の流れ】
  PC(ブラウザ)                  iPhone
  ──────────                    ──────
  ログインボタン押す
  QRコード表示 ─────────────→ カメラで読み込み
                                 生体認証(Face ID等)
                                 セキュアエレメント内で署名
                ←─── 署名データ ─────
  サービスが検証 → ログイン完了
  (秘密鍵はiPhoneから出ない)

ログインするとき、QRコードが表示されます。
それを、たとえば iPhoneのカメラで読み込んで生体認証を通すと、PC側のログインが完了します。
iPhone内の秘密鍵で署名しているのですが、秘密鍵そのものはiPhoneから出dl
ません。

4. まとめ

新しい印鑑を彫り、印影を銀行に登録し、その印鑑を大事に保管する。
パスキーはその操作をボタン一押しで自動的にやっています。

見えないうちに使えます。
見えないから安全です。
でも見えないから、実感が湧きにくい。

「パスキーを登録する」操作の実態は、SSH鍵認証でいう ssh-keygenssh-copy-id を一気に実行することです。
この対応関係がわかると、パスキーが公開鍵暗号という安定した技術を、ウェブの一般利用に持ち込んだものだと見えてきます。

  1. パスキーはFIDOアライアンスとW3Cが策定したFIDO2規格に基づいています。ブラウザとサーバー間の通信を定めるWebAuthnと、デバイスと認証器間の通信を定めるCTAP2という2つの仕様で構成されており、主要なOS・ブラウザはいずれも対応しています。 – FIDO2とは | IBM
  2. ed25519は楕円曲線暗号の一種で、2014年にOpenSSH 6.5で導入されました。128ビットのセキュリティ強度を256ビットの鍵長で実現しており、同等の強度を得るためにRSAでは3072ビット以上の鍵が必要です。現在のSSH鍵生成で最も推奨されるアルゴリズムです。 – SSH 鍵 – ArchWiki
  3. この仕組みはチャレンジレスポンス認証と呼ばれます。サーバーがランダムなデータ(チャレンジ)をクライアントに送り、クライアントが秘密鍵でそのデータに署名して返送します。毎回異なるチャレンジを使うため、過去の通信を盗聴して再利用するリプレイ攻撃に耐性があります。 – チャレンジ/レスポンス認証とは – IT用語辞典 e-Words
  4. 指紋や顔のデータはデバイス内のSecure Enclave(またはAndroid相当のセキュアチップ)で処理され、外部のサービスには一切送信されません。パスキーの認証でサービス側に届くのは、秘密鍵で生成した署名データのみです。 – Passkey(パスキー)とは – CloudGate
  5. AppleデバイスではSecure Enclaveと呼ばれます。iPhone 5s以降のiPhoneやAppleシリコン搭載のMacに搭載されており、メインプロセッサとは物理的に分離されています。OSのカーネルが侵害されても、Secure Enclave内のデータには影響が及ばない設計になっています。 – Secure Enclave – Apple サポート
  6. WebAuthnの仕様では、このドメインの識別子をRP ID(Relying Party ID)と呼びます。パスキーはRP IDに紐付いて生成されるため、たとえ見た目が同じ偽サイトであっても、RP IDが異なれば認証が成立しません。SSHが接続先ホストに紐付くのと同じ発想ですが、WebのURL単位でより厳密に管理されます。 – パスキーとは? – 日立ソリューションズ セキュリティコラム
  7. iCloudキーチェーンに保存されるパスキーはエンドツーエンド暗号化されており、Apple自身もその内容を参照できません。復号に必要な鍵はユーザーのデバイス側にのみ存在します。このクラウド同期の仕組みにより、従来のFIDO2認証が抱えていた「デバイスを紛失したら再登録が必要」という問題が解決されています。 – FIDO パスキー(Passkey)ってなに? – DDS