SSH鍵認証 vs パスワード認証 - なぜ鍵が安全なのか
この記事で解決できること
- SSH鍵認証とパスワード認証の 本質的な違い が分かる
- 「なぜ鍵の方が安全なのか」を 暗号の仕組みから 説明できる
ssh-keygenでの鍵作成・設置・パスワード認証無効化まで 実務の型 が身につく
結論(先に要点)
- パスワード認証は 秘密(パスワード)をサーバ側で照合 する。鍵認証は 秘密(秘密鍵)をクライアントから一切出さない
- 鍵認証は 総当たり攻撃・パスワード使い回し・漏洩リスク に構造的に強い
- 本番サーバは 鍵認証 + パスワード認証無効化 が定番の型
前提(対象環境)
- OpenSSH(Ubuntu / Debian / RHEL 系など一般的なLinuxサーバのSSH実装)
- クライアントもOpenSSH(macOS / Linux / WSL / Windows 10以降)
SSH鍵認証とパスワード認証は何が違うのか?
結論: パスワード認証は「知っている秘密」を毎回サーバへ送って照合する。鍵認証は「持っている秘密鍵」をネットワークに出さずに所有を証明する。
両者は「本人をどう確かめるか」の方式が根本的に異なる。
| 観点 | パスワード認証 | 鍵認証(公開鍵認証) |
|---|---|---|
| 秘密の正体 | パスワード(記憶) | 秘密鍵(ファイル) |
| 秘密の流れ | 暗号化された経路でサーバへ送る | ネットワークに 出さない |
| サーバ側が持つもの | パスワードのハッシュ | 公開鍵(authorized_keys) |
| 突破の主な経路 | 推測・総当たり・使い回し・フィッシング | 秘密鍵ファイルの盗難 |
パスワードは「頭の中の文字列」、秘密鍵は「手元のファイル」。守るべき対象の性質が違うので、対策の考え方も変わる。
なぜ鍵認証の方が安全なのか?
結論: 秘密鍵がネットワークを流れないため盗聴で奪えず、鍵長が事実上総当たり不能で、サーバ側が漏洩しても秘密鍵は復元できないため。
鍵認証の安全性は主に3つの構造から生まれる。
1. 秘密がネットワークを流れない
パスワード認証では、暗号化されているとはいえパスワードそのものがサーバへ届く。鍵認証では秘密鍵はクライアントに留まり、送られるのは 署名(秘密鍵で作った証明)だけ。秘密鍵自体は経路上に存在しない。
2. 総当たりが事実上不可能
人間が覚えられるパスワードは桁数・複雑さに限界があり、総当たり・辞書攻撃の標的になる。一方 Ed25519 や 2048bit 以上の RSA 鍵は、鍵空間が天文学的で総当たりは現実的でない。
3. サーバ漏洩に強い
サーバが保持するのは 公開鍵 だけ。公開鍵から秘密鍵を逆算することはできないため、authorized_keys が流出しても他人がログインできるようにはならない。パスワードのハッシュ流出(オフライン解析の起点)とは前提が違う。
「鍵認証は安全」は 秘密鍵を守れている前提 が成り立つ場合の話。秘密鍵ファイルそのものを盗まれれば突破される。守る対象がパスワードから秘密鍵ファイルに移っただけ、という視点を忘れない。
公開鍵と秘密鍵はどう機能するのか?
結論: クライアントが秘密鍵で署名し、サーバが対応する公開鍵で検証する。秘密鍵を渡さずに「秘密鍵を持っている」ことを証明できる。
鍵認証は 公開鍵暗号 に基づくチャレンジ・レスポンスで成立する。流れは概ね次の通り。
- クライアントが「この公開鍵で認証したい」とサーバへ伝える
- サーバは
authorized_keysに該当する公開鍵があるか確認する - クライアントはセッション固有のデータに 秘密鍵で署名 して返す
- サーバは 公開鍵で署名を検証 する。一致すれば本人と判断する
ポイントは、署名はセッションごとに異なるデータに対して作られるため、過去の通信を盗聴・再生しても次の認証には使えないこと。秘密鍵そのものは一度もネットワークに出ない。
公開鍵 = 配ってよい錠前、秘密鍵 = 手元に隠す鍵、というイメージ。錠前(公開鍵)はサーバに何個でも置けるが、それを開けられるのは対応する鍵(秘密鍵)を持つ本人だけ。
鍵ペアをどう作成して設置するのか?
結論:
ssh-keygen -t ed25519で鍵ペアを作り、ssh-copy-idで公開鍵をサーバのauthorized_keysに設置する。
1. 鍵ペアを作成する
$ ssh-keygen -t ed25519 -C "you@example.com"
-t ed25519:現在の推奨アルゴリズム(高速で安全。古い環境向けには-t rsa -b 4096)-C:コメント(どの鍵か後で識別するための目印)- 生成物:秘密鍵
~/.ssh/id_ed25519と 公開鍵~/.ssh/id_ed25519.pub
途中で パスフレーズ を求められる。これは秘密鍵ファイル自体を暗号化する追加の鍵で、設定を強く推奨する(後述)。
2. 公開鍵をサーバへ設置する
$ ssh-copy-id user@server
ssh-copy-id は公開鍵をサーバの ~/.ssh/authorized_keys に安全に追記し、権限も適切に設定する。手動で行う場合は公開鍵(.pub の方)の中身を authorized_keys に1行追記する。
設置するのは 公開鍵(.pub) だけ。秘密鍵(id_ed25519)をサーバへコピーしてはいけない。秘密鍵は手元のクライアントから出さないのが大原則。
3. 接続を確認する
$ ssh user@server
パスワードを聞かれずに(またはパスフレーズだけで)ログインできれば成功。
パスワード認証は無効化すべきか?
結論: 鍵認証が確実に動くことを確認した上で、本番サーバはパスワード認証を無効化するのが定番。総当たりの入口を物理的に塞げる。
鍵認証を有効にしても、パスワード認証が生きていれば総当たり攻撃の入口は残る。/etc/ssh/sshd_config で無効化する。
# /etc/ssh/sshd_config PubkeyAuthentication yes PasswordAuthentication no
設定後、SSHサービスを再起動する。
$ sudo systemctl restart ssh # Debian / Ubuntu 系 # RHEL 系はサービス名が sshd $ sudo systemctl restart sshd
締め出し事故に注意。 パスワード認証を無効化する前に、必ず 別のターミナルで鍵ログインが成功すること を確認する。現在のセッションは開いたまま、新しい接続でテストするのが鉄則。鍵が動かない状態で無効化すると、自分もログインできなくなる。
秘密鍵を安全に扱うには?
結論: パスフレーズを設定し、
~/.sshと秘密鍵のパーミッションを絞り、ssh-agentで入力負担を減らす。
鍵認証の安全性は秘密鍵を守れている前提に立つ。最低限、次を守る。
パスフレーズを設定する
秘密鍵にパスフレーズを掛けておけば、ファイルを盗まれても即座には使えない。ssh-keygen 実行時に設定するのが最も簡単。
パーミッションを絞る
$ chmod 700 ~/.ssh $ chmod 600 ~/.ssh/id_ed25519 $ chmod 600 ~/.ssh/authorized_keys
OpenSSH は秘密鍵や ~/.ssh の権限が緩いと、安全のため認証を拒否する。権限エラーで弾かれる定番ポイント。
ssh-agent で入力を減らす
$ eval "$(ssh-agent -s)" $ ssh-add ~/.ssh/id_ed25519
ssh-agent にパスフレーズ解除済みの鍵を預けておくと、セッション中はパスフレーズの再入力が不要になる。安全性(パスフレーズあり)と利便性を両立できる。
やってはいけないこと:
- 秘密鍵をメールやチャット、クラウドストレージで共有する
- 秘密鍵を複数人で使い回す(誰の操作か追跡できなくなる)
- パスフレーズなしの秘密鍵を持ち運ぶノートPCに置きっぱなしにする