It’s the first idea I had when it came to making sure login on my server is secure. Instead of having a small password that relies on my fallinble memory and may be also guessed in a not-completely-rodiculous amount of time.
Meanwhile a fairly small file, something like a 512 byte “user.key”, to be uploaded along with your username, or even just having your username built-in, seems much safer.
I wanted to do some math but I could only find limited calculators for doing calculations with such big numbers so have the amount of possible combinations the file may have:
256^512
1,044,388,881,413,152,506,691,752,710,716,624,382,579,964,249,047,383,780,384,233,483,283,953,907,971,557,456,848,826,811,934,997,558,340,890,106,714,439,262,837,987,573,438,185,793,607,263,236,087,851,365,277,945,956,976,543,709,998,340,361,590,134,383,718,314,428,070,011,855,946,226,376,318,839,397,712,745,672,334,684,344,586,617,496,807,908,705,803,704,071,284,048,740,118,609,114,467,977,783,598,029,006,686,938,976,881,787,785,946,905,630,190,260,940,599,579,453,432,823,469,303,026,696,443,059,025,015,972,399,867,714,215,541,693,835,559,885,291,486,318,237,914,434,496,734,087,811,872,639,496,475,100,189,041,349,008,417,061,675,093,668,333,850,551,032,972,088,269,550,769,983,616,369,411,933,015,213,796,825,837,188,091,833,656,751,221,318,492,846,368,125,550,225,998,300,412,344,784,862,595,674,492,194,617,023,806,505,913,245,610,825,731,835,380,087,608,622,102,834,270,197,698,202,313,169,017,678,006,675,195,485,079,921,636,419,370,285,375,124,784,014,907,159,135,459,982,790,513,399,611,551,794,271,106,831,134,090,584,272,884,279,791,554,849,782,954,323,534,517,065,223,269,061,394,905,987,693,002,122,963,395,687,782,878,948,440,616,007,412,945,674,919,823,050,571,642,377,154,816,321,380,631,045,902,916,136,926,708,342,856,440,730,447,899,971,901,781,465,763,473,223,850,267,253,059,899,795,996,090,799,469,201,774,624,817,718,449,867,455,659,250,178,329,070,473,119,433,165,550,807,568,221,846,571,746,373,296,884,912,819,520,317,457,002,440,926,616,910,874,148,385,078,411,929,804,522,981,857,338,977,648,103,126,085,903,001,302,413,467,189,726,673,216,491,511,131,602,920,781,738,033,436,090,243,804,708,340,403,154,190,336
What am I missing? I assume I’m missing something, because the idea of something like this going over a lot of smart programmers and developers’ heads does not sound right
I think because there are ways to protect your entire systems with cryptographic keys - there’s no need for individual applications to do that themselves. You can either only make your network accessible via an SSH tunnel (which would then use SSH-Keys), use a VPN or use mTLS which would require you to install a cert into your browsers key storage.
There’s many good solutions to this problem - no need for individual applications to do it themselves.
Congratulations, now your „password” (the 512-byte random key file) is stored as plaintext on your machine :)
With rate-limiting, non-trivial passwords are not viable to be brute-forced, so making them larger just doesn’t give you much.
Broadly speaking, the private keys can be protected.
For ssh, ssh-agent can retain the viable form for convenience while leaving the ssh key passphrase encrypted on disk. Beyond that your entire filesystem should be further encrypted for further offline protection.
Passkeys as used in webauthn are generally very specifically protected in accordance with the browser restrictions. For example, secured in a tpm protected storage, and authenticated by pin or biometric.
If this is inside the threat model, you put a passphrase on that key and load it in an external process like ssh-agent or gpg-agent. Maybe even move it to a separate physical device like HSMs or crypto hardware wallets (many of which can be used for this purpose btw).
This is also neat: https://doc.qubes-os.org/en/latest/user/security-in-qubes/split-gpg-2.html#notes-about-split-gpg-2
For ssh, ssh keys.
For https, webauthn is the way to do it, though services are relatively rare, particularly for self hosting, partly because browsers are very picky about using a domain name with valid cert, so browsers won’t allow them by ip or if you click through a self signed cert
As someone who implemented webauthn for my $work it was a terrible DX to setup. Webauthn requires an https domain so that alone is going to be a barrier for many self hosted services. Getting the configuration right will also be prohibitive.
Getting a dns name is straightforward enough, and let’s encrypt to get a tla cert…
But for purely internal services that you didn’t otherwise want to publish extremely, the complexity goes way up (either maintain a bunch of domain names externally to renew certificates and use a private DNS to point them to the real place locally, or make your own CA and make all the client devices enroll it. Of course I’m less concerned about passkeys internally.
It’s a pain to manage. If you want to change it, you have to go to each server and update it manually, if you don’t already have automation. If you do have automation, that’s another thing you have to set up and manage. And all that for not much gain.
Not if you use certificates signed by your own internal CA and trust the CA instead of straight up trusting the public keys explicitly.
This way you can generate new SSH or TLS keys trusted across a bunch of machines without having to touch those machines directly for every key, since they are signed by your trusted authority. If you configure CRLs properly you can also revoke them centrally.
If you do have automation, that’s another thing you have to set up and manage.
Hosting a CA is a whole additional service to set up, as is enabling trust for said CA on every server you’re running.
A CA can be an encrypted volume on a live USB stick. It’s mostly for the CRLs you might want something online. A static HTTP server where you manually dump revocations is enough for that.
Unless you do TOFU (which some do and btw how often do you actually verify the github.com ssh fingerprint when connecting from a new host?), you need to add the trust root in some way, just as with any other method discussed. But that’s no more work than doing the same with individual host keys.
And what’s the alternative? Are you saying it’s less painful to log in and manually change passwords for every single server/service when you need to rotate?
Have you heard of ssh keys?
Barely, I’ve had to set one up for GitHub but I haven’t fully figured out what they are and what they do
ssh is a protocol that is used to log in to a computer remotely. Servers are usually administrated not by plugging a keyboard and monitor into the server, but from another machine via ssh. You can configure ssh to allow login with the same username+password you would use locally, but it is common practice to only allow authentication with an ssh key.
ssh keys allow for much higher entropy like you suggested. They are also asymmetric, and the private key can be password-protected or stored on a smartcard.
Oh cool!!! I really ought to set that up on my NAS
Check out TLS client certificates.
- You need the file everywhere. So when lunch time on work I can’t login, it is not my computer but the company machine. Yes, i have my smartphone with me I dont want to send that file to work.
- Easier with password. Easy to setup and to reuse a long password that you already have.
- My ssh server is not reachable easily. Ip restrictions goes a long way and Wireguard is good.
- Congratulations, now your work computer has access to the password (you are not as guillible to think work computer is not recording everything for the stakeholders, are you?)
I think you are looking for SSH certificates.
I think OP is talking about auth in services that you selfhost.
For example elster.de forces you to sign in with one of the many passwordless methods, which includes: entering a username and uploading a cert file.
But most selfhosted services only have username/password logins (if any).
If a service doesnt offer Oidc, just dont self host it. The SSO service can then be properly secured and even if its only a password, at least its not reused.
Just put everything that doesn’t have OIDC behind forward auth. OIDC is overrated for selfhosting.
Yep which is why I use oauth2-proxy between these services and casdoor.
That is certificate based
That sounds like a Passkey
Nope it’s a P12 certificate
It does sound like one, but it isn’t. Ignoring the differences in UX:
Passkey
- Per-service key pair, unique per domain, Identity bound only to that specific account on that site
- Challengeresponse via WebAuthn
- Trust anchored only in the target service (no external CA)
- Private key sealed in OS / secure hardware keystore
Certificate login
- Single global identity usable across many services
- TLS client authentication with certificates
- Trust established via certificate authorities and chain validation
- Private key stored in exportable file or smartcard
Thanks for the explanation!
What you’re looking for is probably something like certificate authentication, or mTLS. It exists, but it’s kind of a pain to set up on client devices so it’s not very common.
What’s more common and easier to set up and is nearly the same thing, is passkey authentication. Same in-flight security characteristics, but you typically need to pass a simple challenge for your device to unlock it.
There are a bunch of self-hosted auth options for both
I’m an admin and using an SSH key is the most common way we log into servers.
Also the most common way I log in to self-hosted servers.
SSH keys are so nice
I’ve got mine hooked into my password manager so it’s as easy as scanning my fingerprint to use (password manager locks on sleep and after a timeout).
What do you do when you need to change your fingerprints?
I keep silicon based backup fingerprints in my lockbox at the credit union.
I have 9 backups.
After that I have to resort to crime and cryogenics.
You can (and should) just use a password manager to generate and store ~64 byte keys which have roughly the same amount of security.
I’m always a little fearful of my password manager leaking or getting hacked, even though I use the longest password I have for it…
If you’re talking about websites, look in to mtls
That’s what SSH keys are essentially.
Or using a hardware key for physical logins.
Both of those basically make your credentials a small encrypted key file instead of password.
Usernames and passwords really only exist as a “convenience”……both for lazy users and bad actors.
For many places, it’s operational inertia. If you’ve had a hosting account at the same place since 1998, you’re bound to still have username/password access to services like FTP even though other (and better) options exist.
And then there is the issue of sole control. Many greybeards like myself still run traditional username/password auth on services because,
- We have whitelisted our IP address, and if dynamic, keep that whitelist updated
- That outside of said whitelisting, the service is a quasi-honeypot meant to protect the machine as a whole. Any connection made from outside the address space of my ISP, by anyone else, is by default considered malicious, and is banned instantly as a precaution. They don’t even get the opportunity to attempt a login; merely connecting to said service is sufficient evidence of hostile intent.
So while my setup is not ideal, it is ideal for myself. if I had anyone else as co-admin, or even clients, things would get stupidly complicated very quickly. But since it’s just me…
Another one: The UX on browsers for managing password is far more developed, and the services you selfhost are accessed via a web browser.









