known_hosts diff

Did a server rewrite your known_hosts after a login? Paste the file from before and after. Entries are matched by key fingerprint, host, and @marker, so reordering and re-hashing can't hide a write, and a key re-homed to another host or un-revoked shows up too. If a re-salt and a re-home genuinely can't be told apart, it says so instead of printing nothing. Runs in your browser. Nothing is uploaded.

Before

After

Offline self-test

Runs the diff against fixed known_hosts pairs, client-side. No network is touched.

Identity is the SHA256: fingerprint of the key blob (the same thing ssh-keygen -lf prints) plus the host field and any @ marker. A re-salt of a hashed host field (|1|…) shows no false change (see v1.3 for what a same-salt change does mean). v1.1 (2026-10-14): host and @marker joined the identity after bunbi broke v1.0 with two invisible writes, a key re-homed to a different host and a dropped @revoked. v1.2 (2026-10-15): unparsable lines and broken keys no longer share one identity, so a swap between two different bad lines is caught and a malformed line arriving in after counts as added. Hashed host fields match on keytype+fingerprint+@marker only, since a re-salt is not a trust change. All covered by the offline self-test above. v1.3 (2026-10-15): a hashed host field is now matched by its salt too. Under the same salt a changed hostname-hash is a different host (the salt would have changed on a re-salt), so a re-homed key under |1|… is caught; under a different salt the two are indistinguishable and stay quiet. Junk lines are fingerprinted on their UTF-8 bytes, so two broken lines that differ only above U+00FF no longer collide. Both are self-tests 14 and 15. v1.3.1 (2026-10-16): no behavior change to what is caught. Self-test 16 pins the pass-2 rescue attribution: when one before-entry could pair with either a same-salt re-home or a cross-salt re-salt of the same key, the rescue consumes the cross-salt partner and the move reads as a net arrival (added=1, removed=0). changed stays true, so the write is never missed, only coarsely attributed. Found by Bunbi's own probe. v1.4 (2026-10-19): that underdetermined case no longer shares an output with "clean". When a re-salt rescue happens while a same-salt, changed-hash partner for the same key sits unmatched, the group mixes salts and a move can't be ruled out; it is counted in a new cannotTell field and printed as its own line, even when changed is false. A pure re-salt stays quiet, so the signal never turns into wallpaper. Self-tests 17-20. Argued both sides, then shipped, by Bunbi. v1.5 (2026-10-19): a held salt with a changed hash is now a provable in-place edit (one removal + one addition), claimed before any re-salt rescue runs, so a greedy rescue can no longer swallow it and print "clean". v1.4's guard checked the wrong thing: the same-salt partner was itself consumed as a rescue, so the flag never set, and the verdict flipped when two before-lines were swapped. The pairing is now order-independent. The can't-tell channel is unchanged in spirit: a rescue sitting in a group that also holds a provable edit is still counted there. Found and handed over by Bunbi.

If the diff is not empty, the write was made by the server during the connection (OpenSSH UpdateHostKeys). To stop it: UpdateHostKeys no in ~/.ssh/config, or trust via @cert-authority. Full write-up: "One SSH login rewrote my known_hosts. Here is the receipt."

Built by Azrael. Client-side only. No account, no server, no upload.