はじめに
git push しようとしたときに、突如UsernameとPasswordを聞かれ混乱しました。それをきっかけにSSH認証の存在を知ることになりました。
調べてみると、パスキーと似てる!?と気づいたのでその共通点や違いについても整理してみました。
対象読者
- GithubをHTTPS認証している人
- SSH認証の理解が曖昧な人
- Webアプリ開発初学者
- パスキーを使ったことあるけど、技術的な仕組みを知らない人
この記事でわかること
- GitHubの認証でHTTPSとSSHがどう違うのか
- なぜSSH認証ではパスワードなしで本人確認できるのか
- 公開鍵・秘密鍵・署名・challengeの関係
- パスキーもSSH認証と似た考え方で動いていること
- パスキーとSSH認証の共通点
- SSH認証とパスキーの違い
- HTTPS・SSH・パスキーを認証方式として比較できるようになる
登場する用語整理
| 用語 | ざっくり説明 |
|---|---|
| HTTPS認証 | GitHubにHTTPSで接続し、ユーザー名とPATなどで本人確認する方式 |
| SSH認証 | GitHubなどにSSHで接続し、秘密鍵と公開鍵を使って本人確認する方式 |
| パスキー | Webサービスへのログインで使われる、秘密鍵と公開鍵を使った認証方式 |
| 秘密鍵 | 自分のPCやスマホの中にある鍵。外には出さない |
| 公開鍵 | GitHubやWebサービスに登録しておく鍵 |
| challenge | サーバーが毎回作るランダムな確認用データ |
| 署名 | challengeに対して秘密鍵で作る、本人確認用の証拠 |
| 検証 | サーバーが公開鍵を使って、署名が正しいか確認すること |
TL;DR
Q&A 形式で理解してみよう
私が実際に理解するまでの思考の変遷を時系列に、Q&Aで整理してみました。
Q1. GitHubでpushしようとしたら、なぜUsernameとPasswordを求められたのか?
A. そのリポジトリのremote URLがHTTPSだからです。
GitHubへpushする方法には、主にHTTPS認証とSSH認証があります。
HTTPS認証の場合、GitHubに対してユーザー名と認証情報を使って本人確認します。
Password欄には通常のログインパスワードを入れるのではなく、Personal Access Token、つまりPATを使います。
Q2. HTTPS認証とSSH認証は何が違うのか?
A. 大きな違いは、本人確認に使うものです。
| 認証方式 | 使うもの | remote URLの例 |
|---|---|---|
| HTTPS認証 | ユーザー名 + PAT | https://github.com/OWNER/REPO.git |
| SSH認証 | 秘密鍵 + 公開鍵 | git@github.com:OWNER/REPO.git |
HTTPS認証では、GitHubに対してユーザー名とPATを使って認証します。
一方、SSH認証では、自分のPCに秘密鍵を置き、GitHubに公開鍵を登録します。
push時には、秘密鍵そのものをGitHubへ送るのではなく、秘密鍵を使って作った署名をGitHubに送ります。
GitHubは、登録済みの公開鍵を使ってその署名を検証します。
Q3. SSHとは何か?
A. SSHは、Secure Shellの略で、安全にリモート接続するための通信プロトコルです。
GitHubにSSHでpushする場合、GitはSSH通信を使ってGitHubに接続します。
自分のPC
↓ SSH通信
GitHub
SSHはGitHub以外にも、Linuxサーバーへのログイン、ファイル転送、SSHトンネルなどで使われます。
今回の記事では、SSH全般ではなく、GitHubにpushするときのSSH認証に絞って扱います。
Q4. SSH鍵はリポジトリごとに作るのか?
A. 基本的にはリポジトリごとではなく、PCやユーザー単位で作ります。
通常は、自分のPCでSSH鍵を作り、公開鍵をGitHubアカウントに登録します。
自分のPC
├─ 秘密鍵
└─ 公開鍵
GitHubアカウント
└─ 公開鍵を登録
この状態にすると、そのGitHubアカウントが権限を持っているリポジトリに対して、同じSSH鍵でpushできます。
Q5. 秘密鍵と公開鍵は何をしているのか?
A. 秘密鍵と公開鍵は、暗号学的に対応した鍵ペアです。
| 鍵 | 置き場所 | 役割 |
|---|---|---|
| 秘密鍵 | 自分のPC | 外に出さない。署名を作る |
| 公開鍵 | GitHub | 署名を検証する |
重要なのは、秘密鍵をGitHubへ送らないことです。GitHubに登録するのは公開鍵だけです。秘密鍵は自分のPCの中に置いたままにします。
Q6. 「秘密鍵で作った署名」とは何か?
A. 署名とは、秘密鍵を持っている人だけが作れる本人確認用のデータです。
流れは次のようになります。
1. GitHubがランダムなデータを出す
2. 自分のPCが秘密鍵でそのデータに署名する
3. GitHubが公開鍵で署名を検証する
4. 検証できれば、対応する秘密鍵を持っていると判断する
コード風に書くと、イメージはこうです。
const challenge = "毎回変わるランダムな値"
const signature = sign(challenge, privateKey)
const ok = verify(challenge, signature, publicKey)
ここで大事なのは、GitHubが秘密鍵そのものを見ているわけではないことです。
GitHubは、秘密鍵で作られた署名を公開鍵で検証しています。
Q7. challengeはなぜ必要なのか?
A. 署名を使い回されないようにするためです。
もし毎回同じデータに対する署名を使っていたら、過去に盗まれた署名を再利用される危険があります。
そのため、GitHubは毎回違うランダムなデータ、つまりchallengeを作ります。
1回目 challenge = A123
2回目 challenge = B987
3回目 challenge = X555
A123に対する署名は、B987の認証には使えません。
つまりchallengeは、署名をその場限りのものにするためにあります。
Q8. SSH認証とパスキーは似ているのか?
A. かなり似ています。
どちらも、秘密鍵を外に出さずに本人確認する仕組みです。
| 仕組み | 秘密鍵の場所 | 公開鍵の登録先 |
|---|---|---|
| SSH認証 | 自分のPC | GitHubなど |
| パスキー | PC・スマホ・認証器 | Webサービス |
SSH認証では、自分のPCが秘密鍵で署名し、GitHubが公開鍵で検証します。
パスキーでも、端末や認証器が秘密鍵で署名し、Webサービスが公開鍵で検証します。
つまり、どちらも基本構造は次のように整理できます。
サーバーがchallengeを出す
↓
端末が秘密鍵で署名する
↓
サーバーが公開鍵で検証する
↓
本人確認できる
Q9. SSH認証とパスキーは何が違うのか?
A. 仕組みの根っこは似ていますが、使われる場面とユーザー体験が違います。
| 観点 | SSH認証 | パスキー |
|---|---|---|
| 主な用途 | GitHub、サーバー接続 | Webサービスへのログイン |
| 主な利用者 | 開発者 | 一般ユーザー |
| 秘密鍵の管理 |
~/.ssh/ など |
OS、ブラウザ、スマホ、認証器 |
| 本人確認 | 秘密鍵、パスフレーズなど | Face ID、Touch ID、PINなど |
| 操作感 | CLIや設定ファイル中心 | ブラウザやOSのUI中心 |
SSH認証は、開発者がGitHubやサーバーに接続するための認証方式です。
パスキーは、一般ユーザーがWebサービスにログインするために、同じような考え方を使いやすい形にしたものだと捉えると理解しやすいです。
Q10. HTTPS認証とSSH認証に優劣はあるのか?
A. 絶対的な優劣はありません。
ただし、用途によって向き不向きがあります。
| 認証方式 | 向いている場面 |
|---|---|
| HTTPS認証 | 一時的にpushしたい、設定を増やしたくない |
| SSH認証 | 継続的に開発する、複数アカウントを使い分けたい |
HTTPS認証は手軽です。
一方で、PATやCredentialの管理で混乱することがあります。
SSH認証は最初に鍵の作成や登録が必要ですが、一度設定すると日常的なpush/pullが楽になります。
普段使う開発PCなら、SSH認証の方が運用しやすいことが多いです。

