I was getting ready to push some changes to this site tonight and got tired of waiting on GitHub's browser login every time. An SSH key fixes that for good. You set it up once, and after that git push just works. Along the way I hit nearly every snag there is, so here are the steps, plus the mistakes I made.
Everything below runs in PowerShell. I tried Cygwin first, and it didn't go well (more on that at the end).
1. Make the key
PS> ssh-keygen -t ed25519 -C "you@example.com"
Press Enter to keep the default location, C:\Users\you\.ssh\id_ed25519. Then press Enter twice for no passphrase, or type one. If you set one, Git asks for it every time you push.
2. Copy the public key, not the fingerprint
When ssh-keygen finishes, it prints a line that starts with SHA256: and ends with your email. That's the key's fingerprint, not the key. I pasted it into GitHub anyway and got this.
Key is invalid. You must supply a key in OpenSSH public key format
The key itself lives in the .pub file. This copies it to the clipboard.
PS> Get-Content $HOME\.ssh\id_ed25519.pub | Set-Clipboard
It's one long line that starts with ssh-ed25519 AAAAC3NzaC1lZDI1NTE5 and ends with your email. Never copy the file without .pub. That one is your private key, and it stays on your machine.
3. Add it to your account, not your repo
The SSH keys page lives in your account settings, not in any repo. The quickest way there is to go straight to github.com/settings/keys while you're signed in. To click your way there, use your profile picture in the top-right corner of any GitHub page, then Settings, then SSH and GPG keys under Access in the left sidebar.
Click New SSH key, give it a title like "Laptop", leave Key type set to Authentication Key, paste the key into the Key box and click Add SSH key.
I first went looking under the repo's own Settings tab. That only has Deploy keys, which work for that one repo.
4. Test it
PS> ssh -T git@github.com The authenticity of host 'github.com (140.82.112.3)' can't be established. ED25519 key fingerprint is SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Hi you! You've successfully authenticated, but GitHub does not provide shell access.
That fingerprint is the one GitHub publishes for its servers, so you know you reached the real GitHub. "No shell access" is normal.
5. Switch your repo from HTTPS to SSH
From inside the repo, this rewrites the remote's address in place, so you don't have to retype the repo name.
PS> git remote get-url origin https://github.com/you/yourrepo.git PS> git remote set-url origin ((git remote get-url origin) -replace '^https://github\.com/', 'git@github.com:') PS> git remote get-url origin git@github.com:you/yourrepo.git PS> git fetch
If git fetch comes back without asking you to log in, you're done.
Why Cygwin ate my passphrase
I started out in Cygwin. It turned out both commands were the Windows versions, not Cygwin's.
$ which git ssh /cygdrive/c/Program Files/Git/cmd/git /cygdrive/c/WINDOWS/System32/OpenSSH/ssh
Windows programs and Cygwin's terminal window don't always agree on hidden typing. ssh-keygen asked for the passphrase twice, I typed the same thing both times, and it still said this.
Passphrases do not match. Try again.
Run ssh-keygen from PowerShell and the problem goes away. Two more Cygwin gotchas: Cygwin's ~ isn't your Windows home folder, so the key is under /cygdrive/c/Users/you/.ssh/. And Cygwin has a handy clipboard device.
$ cat /cygdrive/c/Users/you/.ssh/id_ed25519.pub > /dev/clipboard
If the test just hangs
Some networks block port 22, the usual SSH port. GitHub also answers SSH on port 443, which is almost never blocked. Add this to C:\Users\you\.ssh\config and try again.
Host github.com Hostname ssh.github.com Port 443 User git
One last thing that tripped me up afterward. git pull updates the whole repo wherever it lives. It doesn't drop files into whatever folder you happen to be standing in. I learned that one the slow way.