結論
SSH の秘密鍵をスマホに置くのは、保管方式が正しければ安全です。 具体的には、鍵が端末内で生成され、iOS の Keychain / Android の Keystore にエクスポート不可で保管され、生体認証で保護されているなら、それはノートPCの ~/.ssh/id_ed25519 に平文ファイルとして置く運用より安全です。
危険なのは「スマホであること」ではなく、アプリが鍵をただのファイルとして自分のストレージに置いている場合、そしてPCで作った鍵をクリップボードやクラウド経由でコピーしてきた場合です。前者は端末が侵害されたときに鍵素材がそのまま読み出せますし、後者はコピーの経路そのものが新しい漏洩点になります。
判断に使うべき質問は「Face ID に対応していますか?」ではありません。**「この鍵をアプリからエクスポートできますか?」**です。できてしまうなら、それはファイルです。
以下、保管方式の3階層、ノートPCとの比較、現実的な脅威モデル、そして今日設定できる8項目のチェックリストを順に説明します。
「置き方」で答えが変わる:3つの保管方式
モバイルの SSH クライアントは、見た目が似ていても内部の保管方式が3階層に分かれます。ここを取り違えると、セキュリティ判断が丸ごとずれます。
| 階層 | 秘密鍵の実体 | 端末が侵害されたとき | 見分け方 |
|---|---|---|---|
| 1. アプリ内ファイル | アプリのサンドボックス内のファイル | 鍵素材がそのまま読める(パスフレーズがあればオフライン解析) | 鍵の「エクスポート」「バックアップ」が普通にできる |
| 2. Keychain / Keystore 保管 | OS の鍵ストアに、デバイス固有鍵で暗号化して格納 | パスコード解除が前提。取り出しにはOSレベルの侵害が必要 | エクスポートできない、または警告付き |
| 3. Secure Enclave / StrongBox 生成 | セキュリティチップの内部。外に出ない | 鍵素材は端末外に存在しないため取り出せない | エクスポート不可。署名のたびに生体認証 |
階層1が「スマホに鍵を置くのは危ない」と言われる理由のほぼ全てです。Android/iOS のアプリサンドボックスは強力なので実際にはPCよりマシですが、root/脱獄した端末や、バックアップ経由の吸い出しに対しては無力です。
階層2が現在のモバイル SSH クライアントの標準的な実装で、実用上これで十分です。iOS の Keychain では、kSecAttrAccessibleWhenUnlockedThisDeviceOnly のような「ThisDeviceOnly」クラスの項目はデバイス固有の UID で保護され、別の端末に復元しても復号できません(Apple: Keychain data protection)。つまり、iPhone のバックアップを丸ごと吸われても、そこから鍵を取り出して別の端末で使うことはできません。
階層3が最も堅い構成です。Apple の Secure Enclave 内で生成された鍵は原理的に取り出せず、署名のたびに OS が Face ID / Touch ID のプロンプトを出します。代償は2つ、鍵タイプが ecdsa-sha2-nistp256 に固定されること(Secure Enclave は NIST P-256 しか扱えないため、Ed25519 の Secure Enclave 鍵は存在しません)と、バックアップ・同期・機種変更が一切できないことです。Android での対応物は Keystore の StrongBox(Android 9 / API 28 以降、専用セキュアエレメントを積んだ端末のみ)です。
鍵タイプの選び方そのものは Ed25519 vs RSA にまとめています。なお OpenSSH は 9.5(2023年10月4日リリース)から ssh-keygen の既定が Ed25519 になっており、階層2の鍵を新規に作るなら Ed25519 が素直な選択です。
ノートPCの ~/.ssh と比べて本当に危険か
多くの人が暗黙に比較している対象は「PCなら安全」ですが、この前提は2026年時点ではかなり怪しくなっています。
一般的な開発マシンの ~/.ssh/id_ed25519 は、あなたの権限で動く任意のプロセスから読めるただのファイルです。パスフレーズをかけていても、ファイルがコピーされた時点でオフラインの総当たりが始まりますし、ssh-agent に読み込ませていればメモリ上の鍵が使える状態になっています。npm の postinstall スクリプト、エディタの拡張機能、野良の CLI ツール ── 全部が同じユーザー権限で走ります。
そしてこれは理論上の話ではありません。2025年にはインフォスティーラーによって18億件規模の資格情報が窃取されたと報告されており、Microsoft の2026年6月2日のレポートは、npm パッケージ経由の攻撃キャンペーンが開発者マシンから SSH 鍵・CLI の資格情報・ブラウザデータを窃取していたことを記録しています。ラテラルムーブメントの起点として、~/.ssh は最優先の探索先です。
対してスマホ側は、
- アプリ間のサンドボックス分離が OS レベルで強制され、他アプリがあなたの SSH クライアントのストレージを覗くことは通常できません。
- 任意のスクリプトが自分の権限で走る文化がない(ビルドツールもパッケージマネージャも動いていません)。
- 鍵ストアがハードウェア支援で暗号化されており、ロック中は復号鍵が導出できません。
つまり本当の比較軸は「スマホ vs PC」ではなく、**「サンドボックス化された鍵ストア vs 誰でも読めるホームディレクトリのファイル」**です。この比較なら、条件を満たしたスマホの方が勝ちます。
スマホが不利になるのは1点だけ ── 物理的に持ち歩いていて、失くしやすく、盗まれやすいことです。ここが次の節の本題になります。
現実的な脅威モデル
「安全か」を一般論で議論しても答えは出ません。想定する攻撃者ごとに、スマホの秘密鍵がどうなるかを分けて考えます。
| 脅威 | スマホの鍵はどうなるか | 効く対策 |
|---|---|---|
| ロック状態での端末盗難・紛失 | 実用上は取り出せない(デバイス鍵で暗号化、パスコード必須) | 6桁以上のパスコード、リモートワイプ、サーバー側で1行削除 |
| パスコードを覗き見された上での盗難 | 最大の脅威。 解除できれば正規の操作として鍵が使える | iOS 盗難デバイスの保護、Android Identity Check、アプリ側の生体ロック |
| 端末上のマルウェア | 階層1なら読まれる。階層2/3なら OS レベルの侵害が必要 | 公式ストアのみ、root/脱獄しない、OS を最新に |
| クラウド同期・バックアップからの漏洩 | 平文同期なら致命的。ThisDeviceOnly / E2EE なら実質無効 | 秘密鍵は同期しない、するならクライアント側暗号化のみ |
| アプリ提供者そのもの | 実装次第。鍵をサーバーに送信するクライアントは論外 | エクスポート可否とプライバシーポリシーを確認 |
| 端末の下取り・売却時の残留 | 消し忘れた鍵が生き続ける | 手放す前に authorized_keys から該当行を削除 |
注目すべきは2行目です。ロック中の端末はほぼ堅牢なので、現実の侵害はほぼ全部「解除済みの端末を手に入れた攻撃者」の形をとります。カフェや電車でパスコードを盗み見てから端末を奪う手口が典型です。
OS 側の対策はこの数年でかなり進みました。iOS では iOS 17.3 以降の「盗難デバイスの保護」が、見慣れない場所で重要な操作を行う際に生体認証 → 1時間待機 → 再度生体認証という遅延を課します(Apple サポート)。パスコードだけでは Apple ID のパスワード変更も端末パスコードの変更もできません。Android 側は Identity Check が Android 15 以降で導入され、Google の2026年1月の発表では、信頼できる場所の外では BiometricPrompt を使う全アプリで PIN やパターンへのフォールバックを禁止するところまで拡張されています。Theft Detection Lock や Remote Lock は Play サービス経由で Android 10 以降に配信されています。
SSH クライアントを選ぶときの実務的な意味: アプリ自身が生体認証ロックを持ち、かつ端末側でこれらの盗難対策が有効になっていれば、「解除済み端末を奪われる」シナリオでも攻撃者は追加のハードルを踏むことになります。
スマホに鍵を置くなら:8つの設定
効果の大きい順に並べています。1と2だけでも今日やる価値があります。
1. 端末ごとに専用の鍵を1本、端末内で生成する。 PC の鍵をコピーしてこないでください。コピーは必ずクリップボード・メール・クラウドのどれかを通過し、そこが新しい漏洩点になります。スマホ側で新規に ed25519 鍵を作り、公開鍵だけをサーバーに送ります。手順は iPhone で SSH 鍵を作成する方法 と SSH 公開鍵をサーバーに登録する にあります。
2. 鍵のコメントに端末名を入れる。 iphone15-termai のように書いておくと、authorized_keys が「どの端末がこのサーバーに入れるか」の監査可能な一覧になります。失くしたときに消す行が一目で分かります。
3. エクスポート不可の保管を選ぶ。 アプリの鍵生成画面に「Secure Enclave」「ハードウェア鍵」「生体認証で保護」といった選択肢があるならそれを選びます。エクスポートできてしまうかどうかを、実際に試して確認してください。
4. 端末のパスコードを6桁以上(できれば英数字)にし、生体認証を有効にする。 ここが崩れると上の全部が無意味になります。
5. OS の盗難対策を有効にする。 iOS は「設定 → Face ID とパスコード → 盗難デバイスの保護」を常に要求に。Android は Identity Check と Theft Detection Lock を有効にします。
6. アプリ側の生体ロックを有効にする。 アプリ起動時ではなく、可能なら接続ごとに認証を要求する設定があればそちらを選びます。解除済み端末を奪われたときに効くのはこの層です。
7. 秘密鍵は同期しない。 ホスト一覧やスニペットは同期しても構いませんが、秘密鍵は端末ごとに別物にします。どうしても同期するなら、クライアント側暗号化で事業者が復号できない実装に限ります。
8. 破れたときの復旧経路を先に用意する。 VPS プロバイダの Web コンソール、Proxmox、IPMI、物理キーボード ── どれか1つは必ず。**年に一度は実際に使えるか試してください。**深夜に必要になってから動かないと分かるのが最悪です。オフラインに保管した break-glass 鍵も併用します。
パスフレーズについては、階層2/3で保管されている端末内生成の鍵なら追加価値は限定的です。パスフレーズが守るのは「鍵ファイルがコピーされた後」であり、コピーできない鍵にはその攻撃が成立しないためです。詳しくは SSH 鍵のパスフレーズ を参照してください。
サーバー側で効かせる保険
クライアント側だけで完結させないのが実務の運用です。スマホの鍵は権限を絞った別の鍵として扱います。
接続元を絞る。 authorized_keys の各行の先頭にはオプションを書けます。
from="100.64.0.0/10",no-agent-forwarding,no-port-forwarding ssh-ed25519 AAAAC3Nz... iphone15-termai
from= で接続元を Tailscale のアドレス帯や自宅の固定 IP に限定すると、鍵が漏れても使える場所が激減します。エージェント転送とポート転送はスマホ用の鍵には基本的に不要なので落としておきます。
用途を固定する。 特定のコマンドしか実行させたくない鍵なら command="/usr/local/bin/restart-web" を付けます。「深夜にサービスを再起動するためだけの鍵」を作れます。
root 直ログインは禁止。 PermitRootLogin no は前提条件です(root ログインの無効化)。スマホの鍵は一般ユーザー+必要最小限の sudo に紐づけます。
22番をインターネットに晒さない。 一番効く対策がこれです。SSH ポートを公開せず、Tailscale などのオーバーレイネットワーク 越しにだけ到達可能にすると、総当たりも脆弱性スキャンもそもそも届きません。CGNAT 配下の自宅サーバーにも同じ仕組みで入れます。公開せざるを得ない場合は fail2ban を併用します。
ホスト鍵の警告を無視しない。 スマホは新しいネットワークを次々に渡り歩くので、中間者攻撃の機会は PC より多いです。初回接続のフィンガープリント確認は形式ではなく実質的な信頼判断です(ホスト鍵と TOFU、Host key verification failed の対処)。
パスワード認証を切る。 鍵ログインが別セッションで確実に通ることを確認した後で PasswordAuthentication no にします(SSH 鍵 vs パスワード)。
置くべきでない場合
正直に線を引きます。以下に当てはまるなら、スマホに鍵を置くのは見送るべきです。
- その鍵が「全部入り」の鍵である場合。 本番全台に root で入れる1本の鍵をスマホに持ち込むのは、保管方式に関係なく設計ミスです。まず鍵を分けてください。
- 端末が管理外・共有端末・root/脱獄済みである場合。 サンドボックスと鍵ストアという前提そのものが崩れます。
- 勤務先のポリシーが持ち出しを禁じている場合。 技術的な安全性とは別レイヤーの話で、こちらが優先します。監査上、鍵の所在を証明できないことが問題になるケースもあります。
- アプリがエクスポート可能なファイルとして鍵を保管し、かつ平文でクラウド同期する場合。 これは「スマホに置く」リスクではなく「そのアプリを使う」リスクです。
- 復旧経路が1つもない場合。 端末を失った瞬間にサーバーへの到達手段が消えるなら、鍵を置く前にコンソールアクセスを整備してください。
端末を失くしたら:最初の15分
手順を先に決めておくと、実際に起きたときの被害が桁違いに小さくなります。
- 端末をロック・消去する。 iPhone は「探す」、Android は Find Hub からリモートロック。ここで時間を使いすぎないでください。本命は次の手順です。
- サーバー側で該当行を削除する。 各サーバーの
~/.ssh/authorized_keysから、その端末のコメントが付いた1行を消します。この時点でその鍵は完全に無効になるので、端末が戻ってこなくても構いません。1台1鍵にしておいた効果がここで出ます。 - オーバーレイネットワークから端末を失効させる。 Tailscale の管理コンソールでそのデバイスを削除・失効させます。
- 痕跡を確認する。
last、journalctl -u ssh、/var/log/auth.logで、紛失後のログインがないかを見ます。sudo の実行履歴も確認します。 - パスワード認証が有効なままなら無効化する。 鍵を消しても、パスワードが生きていれば別経路が残ります。
逆に言えば、この5手順が15分で終わる状態を平時に作っておくことが「スマホに鍵を置いても安全」の実質的な中身です。「1台1鍵+コメント+復旧経路」が揃っていれば、端末紛失はインシデントではなく作業になります。
TermAI での扱い
私たちの製品の話なので、宣伝抜きで事実だけ書きます。
TermAI は鍵を端末内で生成またはインポートし、iOS Keychain / Android Keystore に保管します。秘密鍵はサーバーに送信されず、クラウド同期を有効にした場合もクライアント側で暗号化されます。アプリへのアクセスには Face ID / 生体認証をかけられます ── 上の分類で言えば階層2 + アプリロックです。Secure Enclave 生成の ecdsa-sha2-nistp256(階層3)を独立した鍵タイプとして提供しているかどうかは、その時点の製品ドキュメントとアプリ内の鍵生成画面が正となります。
鍵の保管と同じくらい重要なのが、その鍵で何が実行されるかです。TermAI の AI は意図的に「提案型」で、journalctl や systemctl のコマンドを入力行に書くだけで、実行するかどうかは人が判断します。ハードウェア保護された鍵と自動実行エージェントの組み合わせは筋が悪い ── 盗めない資格情報をわざわざ用意した上で、その使用を止まらないループに委ねることになるからです。この議論は AI のシェル提案をどこまで信じるか に詳しく書いています。
無料枠は AI 提案が1日5回、SSH と SFTP は無制限で、内蔵の Tailscale を使えば 22番を公開しないまま自宅サーバーや VPS に到達できます。スマホからの運用全体の組み立て方は スマホからサーバーを管理する を参照してください。