Raspberry Pi: update it, key it, lock it
420-302-VA · WEEK 3 · FALL 2026

Stage 3 of 6 · Theory idea + lab · about 25 minutes

SSH keys

A password is a secret you retype everywhere, so it can be guessed, watched or leaked. A key pair splits the secret: the private half never moves, the public half goes wherever you want to log in. Today you set that up twice: lab PC → Pi, and Pi → GitHub.

What SSH actually does

SSH, the Secure Shell, solves two separate problems every remote login has:

  • Privacy. Everything between the two machines is encrypted. Whoever is on the same Wi-Fi sees traffic, but not your commands, your output or your password. This part is automatic; you never configure it.
  • Identity, twice. First the server proves who it is to you, then you prove who you are to the server. Today's page is about upgrading the second half from passwords to keys.
Every SSH connection: step 1, the server presents its host key and the client checks it against known_hosts; step 2, the user authenticates with a key or a password; then the encrypted session runs 1Server proves itselfhost key vs known_hosts 2You prove yourselfyour key, or a password ✓Encrypted sessionterminal · scp · git
Two identity checks, in order. Week 2's "are you sure you want to continue connecting?" question was step 1: your first meeting with the Pi's host key.

Step 1 explains something you already lived through. Every SSH server, your Pi included, generated its own host key pair at first boot. The first time you connect, your client shows that key's fingerprint and asks whether to trust it; say yes and it is stored in ~/.ssh/known_hosts. From then on the check is silent, and it protects you against connecting to an impostor machine: if the key ever changes unexpectedly, SSH refuses loudly. So the Pi has keys about itself (host keys), and today you add keys about you (user keys). Same mathematics, two different questions.

Read more

Plain-language overviews: Cloudflare's What is SSH? and the SSH Academy's introduction to the protocol and public-key authentication. The precise reference for every option used below: the ssh-keygen manual page.

The key-pair idea

The private key stays on the machine where it was made. Only the public key is copied: from the lab PC to the Pi's authorized_keys, and from the Pi to GitHub's SSH keys page. Lab PC private key · stays here public key (.pub) Raspberry Pi authorized_keys ← copy its own private key GitHub SSH keys ← copy ssh-copy-id paste .pub on the site Green (public) halves travel. Red (private) halves never do. Login works when your private key matches a public key the other side holds.
Two directions, one rule. The lab PC's public key goes onto the Pi so you can log in without a password. The Pi's public key goes onto GitHub so git push works without one.

Why can the public half be public? The pair is asymmetric: what one key locks, only the other unlocks. Think of the public key as an open padlock you can hand out freely; anyone can snap it shut on a challenge, but only your private key opens it. When you connect, the server locks a random challenge with your public key, and producing the answer proves you hold the private key, which itself is never transmitted. Nothing to guess, nothing to shoulder-surf, nothing to reuse from a leaked password list. A password, by contrast, is a shared secret: the server must hold something derived from it, and you retype it on every machine, which is exactly what makes it phishable and reusable.

Generate a pair on the lab PC

On the lab PC (Windows PowerShell, macOS Terminal or Linux terminal). ed25519 is the modern, short, fast key type:

$ ssh-keygen -t ed25519 -C "lab-pc"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/username/.ssh/id_ed25519):   # Enter = default
Enter passphrase (empty for no passphrase):                              # see below
  • Accept the default file name. Tools look for it there.
  • The -C comment just labels the key ("lab-pc", "home-laptop") so you can tell them apart later.
  • Passphrase: it encrypts the private key file itself, a second layer if the file is stolen. On a shared lab PC, set one; on your own laptop it is your call. Empty is allowed.
  • Result: ~/.ssh/id_ed25519 (private, red in the diagram) and ~/.ssh/id_ed25519.pub (public, green).

Already have a key on this machine?

ssh-keygen warns before overwriting. Keep the existing pair and skip to the next step; one pair per machine is the normal setup.

Install it on the Pi

ssh-copy-id appends your public key to ~/.ssh/authorized_keys on the Pi, with the right permissions. It asks for your Pi password one last time:

$ ssh-copy-id username@lastname-pi.local    # your-username@your-hostname.local
Number of key(s) added: 1
$ ssh username@lastname-pi.local            # test: no password prompt (a passphrase prompt is the key's, not the Pi's)

If ssh-copy-id is missing (some Windows setups), do it by hand; this is exactly what the tool automates:

$ type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh username@lastname-pi.local "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"   # PowerShell

Password login stays on, on purpose

Real servers often disable password login after installing keys (PasswordAuthentication no in /etc/ssh/sshd_config). In this lab we leave passwords enabled: the drive changes hands weekly and a lost key would lock you out of your own installation. Know that the option exists; do not set it on the class drive.

A key for GitHub

Same idea, other direction: the Pi generates a pair, and GitHub holds the public half, so pushes from the Pi need no password or token typing. On the Pi:

  1. Generate and show the public key

    $ ssh-keygen -t ed25519 -C "lastname-pi"
    $ cat ~/.ssh/id_ed25519.pub
    ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... lastname-pi

    Select the whole output line and copy it.

  2. Add it on the site

    GitHub → your profile photo → Settings → SSH and GPG keys → New SSH key. Title: lastname-pi. Paste the line. GitHub's own walkthrough with current screenshots: Connecting to GitHub with SSH.

  3. Test the connection

    $ ssh -T git@github.com
    Hi username! You've successfully authenticated, but GitHub does not provide shell access.

    That sentence is success. Accept the fingerprint prompt the first time with yes.

  4. Use the SSH address for your repository

    $ git clone git@github.com:username/a1-repo.git       # SSH form, not https://
    $ git remote set-url origin git@github.com:username/a1-repo.git   # switch an existing clone

    An https:// remote keeps asking for credentials; the git@github.com: form uses your new key. You will push with it during the Assignment 1 demo.

Key hygiene

  • Never copy, mail, commit or screenshot the private key (the file without .pub). Not to your teammate, not to a repository, not to the teacher.
  • Sharing the .pub file or a fingerprint (ssh-keygen -lf ~/.ssh/id_ed25519.pub) is always safe.
  • Permissions matter: ~/.ssh must be 700 and key files 600, or SSH refuses to use them. ssh-keygen and ssh-copy-id set this correctly; hand-copied files sometimes need chmod 600 ~/.ssh/authorized_keys.
  • One pair per machine, a comment naming the machine, and delete a machine's key from the Pi and GitHub when you stop using that machine. Removal is just deleting its line from authorized_keys or the GitHub list.
  • If a private key may have leaked, you do not "change its password": you delete the pair, generate a new one, and remove the old public key everywhere it was installed.

Checklist for this stage

Check yourself

Which file may be freely shared, and which must never leave its machine?
The .pub file is public by design; paste it anywhere you want to log in. The file without an extension is the private key; it stays where ssh-keygen created it, always.
After ssh-copy-id, SSH still asks for something. When is that normal?
If it asks for your key's passphrase, that is normal: it unlocks your local private key. If it asks for the Pi account password, the key was not installed; rerun ssh-copy-id and check ~/.ssh permissions on the Pi.
Why does the Pi get its own key pair for GitHub instead of reusing the lab PC's?
The private key never moves between machines. Each machine that needs to authenticate generates its own pair, and GitHub can hold many public keys. That also lets you revoke one machine without touching the others.
What does "Hi username! ... does not provide shell access" mean?
Authentication worked. GitHub deliberately refuses an interactive shell; the message is the success case of ssh -T git@github.com.
A teammate accidentally pushed their private key to the A1 repo. What now?
Treat it as leaked: generate a new pair, add the new public key to GitHub and the Pi, delete the old public key from both, and remove the file from the repository. Deleting the file alone does not help; the key lives on in the Git history.