macOS Secure Enclave を使った SSH キーの保護(ネイティブアプローチ)
Protecting SSH Keys with macOS Secure Enclave (gatezh.com)
要約
この記事では、macOS の Secure Enclave を利用して SSH キーを保護するネイティブな方法について解説しています。筆者は当初、この方法を試しましたが、UI の使いにくさから最終的には採用を見送りました。しかし、セキュリティ面では非常に強力であり、鍵がハードウェアから流出しないという利点があることを強調しています。
全文翻訳
macOS Secure Enclave を使った SSH キーの保護(ネイティブアプローチ)
私はしばらくの間、SSH キーの安全性について神経質になっていました。それらは単に ~/.ssh/ に置かれており、ファイルパーミッション以外に何も保護がありません。私のファイルシステムにアクセスできる悪意のあるスクリプトがあれば、それらをコピーしてすべてのサーバーに侵入できてしまいます。また、オンライン上では、リポジトリをクローンしてローカルマシンで実行するように求める偽の面接課題に関する多くの話がありました。これが私が devcontainers に完全に切り替えた理由の一つですが、それすらも私には十分ではありませんでした(そして、実際にはあなたや他の誰にとっても十分であるべきではありません)。
そこで、ついにそれに対処することにしました。
TL;DR
私は、ネイティブな macOS Secure Enclave アプローチ(既製ツールのみを使用)は、結局のところ非常に醜く、我慢できなかったため、採用しないことにしました。しかし、これは完全に機能する、実用的なソリューションであり、そうでなければ間違いなく使用するでしょう。
オプション
いくつかの調査の結果、SSH キーを保護する方法がいくつか見つかりました。
- ネイティブ macOS Secure Enclave — サードパーティ製アプリなし、OS に組み込み
- Secretive — Secure Enclave にキーを保存するサードパーティ製アプリ
- YubiKey — FIDO2 をサポートするハードウェアセキュリティキー
- 1Password / Bitwarden — キーを暗号化されたボールトに保存し、それらの SSH エージェントを使用する
私はすでに 1Password を使用していますが、将来的には別のものに切り替えるかもしれません。Bitwarden は最近 SSH キーサポートを追加しました(無料ティアでも!)。しかし、それはまだソフトウェアソリューションです。キーは保存時に暗号化されますが、使用時にはメモリ内で復号化されます。
私が本当に欲しかったのは、ハードウェアベースのセキュリティでした。たとえ私の Mac が完全に侵害されたとしても、秘密鍵は文字通り抽出不可能であるべきです。
これにより、YubiKey または Secure Enclave が残りました。私は YubiKey 5C を持っていますが、まずネイティブアプローチを試したかったのです。持ち運ぶ追加のハードウェアなし、維持するサードパーティ製アプリなしで済みます。
Secure Enclave SSH とは?
macOS Sequoia (および Tahoe) 以降、macOS は Secure Enclave にバックアップされた SSH キーをサポートしています。Secure Enclave は、Mac のチップ上のセキュリティサブシステムであり、メインプロセッサから分離されています。秘密鍵は内部で作成され、決して外部に出ることはありません。
SSH でどこかに接続する際、Mac は Secure Enclave に認証チャレンジに署名するように要求します。Touch ID を有効にすると、各署名操作を承認する必要があります。実際の秘密鍵は、メモリやディスクに存在するわけではありません。
ワークフローは、通常の SSH キーと驚くほど似ています。
| アスペクト | 通常の SSH キー | Secure Enclave キー |
|---|---|---|
| 秘密鍵の場所 | ~/.ssh/id_ed25519 (ファイル) | Secure Enclave |
| ディスク上のもの | 実際の秘密鍵 | 単なる参照(この Mac なしでは無用) |
| リモートサーバーでのセットアップ | 公開鍵を authorized_keys にコピー | 同じ |
| 接続 | 問題なく動作 | Touch ID プロンプト、その後動作 |
セットアップ
ステップ 1: Secure Enclave キーの作成
macOS は、CryptoTokenKit ID を管理するために sc_auth コマンド(Smart Card Authentication)を提供しています。名前はスマートカード認証ですが、Secure Enclave でも機能します。
sc_auth create-ctk-identity -l "ssh-MacBook" -k p-256-ne -t bio
これを分解すると:
-l "ssh-MacBook"— 参照用のラベル(ローカルでのみ表示可能)-k p-256-ne— NIST P-256 カーブ、non-exportable(鍵は Secure Enclave から決して出られない)-t bio— すべての使用に生体認証(Touch ID)を要求する
キーを作成するために Touch ID を求められます。
問題 1: Touch ID エラー
私が最初にこのコマンドを実行したとき、恐ろしいエラーが発生しました。
Error: Error Domain=NSOSStatusErrorDomain Code=-25293 "Failed to generate keypair"
(errKCAuthFailed / errSecAuthFailed: / Authorization/Authentication failed.)
UserInfo={..., NSUnderlyingError=... "Failed to get bio catacomb UUID for user 502." ...}
どうやら私の Touch ID 登録が何らかの理由でリセットされたようです。システム設定 → Touch ID とパスワードで指紋を再登録した後、コマンドは正常に動作しました。
キーが作成されたことを確認できます。
sc_auth list-ctk-identities
出力:
Key Type Public Key Hash Prot Label Common Name Valid To Valid
p-256-ne A71277F0BC5825A7B3576D014F31282A866EF3BC bio ssh-MacBook ssh-MacBook 2027-01-26, 10:18 YES
ステップ 2: キーハンドルのエクスポート
次に、SSH が使用できる「キーハンドル」ファイルを作成する必要があります。これは秘密鍵ではありません。SSH に「Secure Enclave に署名を要求するように」と伝える参照にすぎません。
ssh-keygen -w /usr/lib/ssh-keychain.dylib -K -N ""
PIN を求められたら、Enter キーを押すだけです(生体認証キーには使用されません)。Touch ID がポップアップ表示されます。これにより、現在のディレクトリに id_ecdsa_sk_rk と id_ecdsa_sk_rk.pub が作成されます。
それらを SSH ディレクトリに移動します。
mv id_ecdsa_sk_rk* ~/.ssh/
ステップ 3: SSH を Secure Enclave プロバイダーで使用するように設定する
これを ~/.zshrc(または ~/.bashrc)に追加します。
export SSH_SK_PROVIDER=/usr/lib/ssh-keychain.dylib
シェルをリロードします。
source ~/.zshrc
問題 2: あちこちにある古いコマンド
もし「macOS Secure Enclave SSH」でオンライン検索すると、ssh-add -K を実行するように指示するガイドがたくさん見つかるでしょう。やめてください。これは非推奨です。
WARNING: The -K and -A flags are deprecated and have been replaced
by the --apple-use-keychain and --apple-load-keychain
flags, respectively.
そして、新しいフラグでさえ Secure Enclave キーでは機能しません。それらは従来の macOS Keychain 用であり、CryptoTokenKit 用ではありません。SSH_SK_PROVIDER 環境変数が正しいアプローチです。
ステップ 4: 公開鍵を取得する
cat ~/.ssh/id_ecdsa_sk_rk.pub
出力:
sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTIt... ssh:
末尾の ssh: は FIDO2 アプリケーション ID です。これはキーの一部であり、コメントではありません。authorized_keys にコピーする際に、その後に独自のコメントを追加できます。
sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTIt... ssh: macbook-secure-enclave
ステップ 5: サーバーにコピーする
ssh-copy-id -i ~/.ssh/id_ecdsa_sk_rk.pub user@your-server
または、サーバー上の ~/.ssh/authorized_keys に公開鍵(コメント付き)を手動で貼り付けます。
ステップ 6: ~/.ssh/config を設定する
問題 3: SSH がキーを見つけられない
すべてを設定した後、SSH を試しましたが… パスワードを求められました。
詳細出力(ssh -vvv)は、SSH が古い RSA キーのみを試していることを示しました。
debug1: Offering public key: /Users/sergii/.ssh/id_rsa RSA SHA256:...
問題:SSH は id_ecdsa_sk_rk という名前のファイルを自動的に検索しません。id_rsa、id_ed25519、id_ecdsa のような標準名のみを自動検出します。
修正方法は、~/.ssh/config に明示的に追加することです。
Host *
IdentityFile ~/.ssh/id_ecdsa_sk_rk
IdentityFile ~/.ssh/id_rsa
IdentityFile ~/.ssh/id_ed25519
SSH はアイデンティティファイルを順番に試行するため、デフォルトにしたい場合は Secure Enclave キーを最初に配置してください。
⚠️ 注意: 1Password の SSH エージェント(IdentityAgent)を使用している場合、この設定と競合する可能性があります。テスト中はコメントアウトする必要がありました。
ステップ 7: テストする
ssh user@your-server
Touch ID プロンプトが表示され、接続されるはずです。
すべてに対する Touch ID の醜さ
[画像: Touch ID プロンプト]
Touch ID プロンプト
私が気に入らない点の一つは、Touch ID ダイアログに「SSH がキーを使用したい」のような親切なメッセージではなく、「ctccardtoken が続行するために認証する必要があります」と表示されることです。
これは、プロンプトが CryptoTokenKit — Apple がエンドユーザー向けに洗練させていない低レベルフレームワーク — から来ているためです。これが気になる場合は、Secretive が、バックグラウンドでは Secure Enclave を使用しながらも、はるかに優れた UI を提供します。
なぜすべてに Touch ID を使うのか?
当初、2 つのキーを作成することを考えていました。1 つは「重要な」サーバー用の Touch ID 付き、もう 1 つは利便性のための Touch ID なし(Git 操作など)です。
しかし、その時気づきました。-t bio なしでは、マルウェアが私のキーをサイレントに使用できてしまいます。-t bio があれば、私の SSH キーが使用されているときを常に知ることができます。1 日あたり数回の追加タップは、その可視性のための小さな代償です。
したがって、SSH キーをこのように保存することを計画している場合の私の推奨事項は、すべてに -t bio を使用することです。もしそれが煩わしくなったら、後でいつでも 2 つ目のキーを作成できます。
キャッチ: バックアップなし
Secure Enclave キーは、特定の Mac に紐付けられています。Mac が壊れたら、キーも失われます。
これは意図したものです。鍵はエクスポートできないため、バックアップもできません。代わりに、複数のキーを保持してください。Secure Enclave キーとバックアップキー(YubiKey または別の Mac から)をサーバーの authorized_keys に追加します。1 つのデバイスを紛失しても、もう一方を通じてアクセスできます。
最終的な考え
SSH キーを安全に保存するための適切な方法のようです。そして、ハードドライブに保存するよりもはるかに優れています。
上記の実装により、以下が得られます。
- ✅ 秘密鍵は文字通り盗むことができない(ハードウェア内にある)
- ✅ すべての SSH 操作で Touch ID が必要(キーがいつ使用されているかを知ることができる)
- ✅ サードパーティ製アプリは不要
- ✅ 既存の
authorized_keysワークフローで動作する
しかし、UI の醜さにはやや驚かされました。Apple がなぜこれほど洗練されていないものをリリースしたのか分かりません。すべてのプレゼンテーションでセキュリティに関するセクション(Apple ロゴが Apple ロックになる場所)がありますが、セキュリティ機能には実際に美的に魅力的な外観を期待していました。それは間違いなくそうではありません。私の美意識はこの醜さとは相容れないため、Secretive のような、Secure Enclave に SSH キーを保存するための他のソリューションを検討することになります。
また、Mac に何かあった場合に備えて、バックアップオプションもまだ必要です。