Essential SSH key management best practices for Ubuntu systems, including generation, protection, rotation, and backup strategies for maintaining secure and efficient server access.
seen from Türkiye

seen from United States

seen from Germany
seen from China

seen from United States

seen from United States
seen from China

seen from Switzerland

seen from Switzerland

seen from Switzerland
seen from Switzerland
seen from Philippines
seen from Australia
seen from United Kingdom
seen from Italy
seen from China
seen from Australia
seen from United States
seen from Switzerland

seen from Japan
Essential SSH key management best practices for Ubuntu systems, including generation, protection, rotation, and backup strategies for maintaining secure and efficient server access.
So last year I started writing that if I was to implement asymmetric passwords right now, I would use Argon2id for key derivation, Ed25519 for signatures, and Ristretto255 for the OPRF. I haven't really reviewed those choices since, but they are probably still good.
Argon2id output size must match the private key size of Ed25519: 256 bits.
The other Argon2id parameters can just be left configurable in the implementation, but there are some universally applicable ideas:
You are competing with the insecurity of just sending the plain password to the server. Any parameters are profoundly more secure than that. The private key derived with this Argon2id run never leaves your client and is only around in memory momentarily. The server only sees that private key's signatures and public key.
The key UX consideration is how much time it takes and how much it bogs down the user's device from doing anything else useful while logging in. Unfortunately many users in the world still have fairly low-spec hardware, and you are competing with the speed of sending their password with plain text.
The recommended Argon2 tuning order is to raise memory as much as you can - the whole point of Argon2 is to be memory hard to take away any cost advantage from GPU, FPGA, and ASIC crackers - then raise the parallelism, then raise the iterations.
So that lets us figure out the best parameters that can be used across all devices with some minimum specs that we want to support while still having an acceptably fast login experience on all of them.
And obviously for users who know to seek out those settings, we could also let users raise their account's minimum Argon2id parameters higher than the default minimum.
But can we do even better?
In principle we could always have higher parameters than our secure minimum while keeping acceptably fast logins if the user's device has the specs for it. This just adds a small risk of a slow login if they later try to log in from an atypically low-spec or constrained system.
So why not just automate that process? First try to get larger allocations until the system refuses, while also doing a microbenchmark to test if using that much memory at once hits a slowdown. Then do a microbenchmark to see when speedup from parallelism drops off. You might be able to combine these two. Now start running an Argon2id implementation that gives you some way to choose at each iteration whether to stop or continue, and stop once you're less than one iteration's duration away from your maximum acceptable login time.
This is getting better, but what do you do for users who log in from devices with significantly different specs? Maybe they dropped and broke their phone so they're using an old temp phone for a while. Or they normally log in from a high-end gaming rig but today they're at grandma's and hopping on her budget computer to get something done.
When a user logs in, we have to use the saved parameters to check their login, otherwise Argon2id would give us a different private key and the Ed25519 public key wouldn't match the saved one.
But if the measured best parameters are different enough, then after logging in successfully we could start the creation of a new entry as a background lower-priority task.
Unless the user leaves in about a login's worth of time right after logging in, that will finish and we can save that so the login uses the best settings next time.
Okay but what about churn if you use multiple devices regularly? What about needlessly sending a less secured key after throwing away more secure parameter entry? What about needlessly spending more time logging in after throwing away a lower parameter entry?
We could actually have more than one entry of Argon2id parameters, salt, and public key for a user. So long as the minimum parameters meet our security bar, the only downside is a tiny risk of a weakness in the composition of Ed25519 deriving public keys from separate private keys that result from independently randomly salted and differently parameterized Argon2id runs somehow leaking statistical information about the password.
Each entry can be expired once it hasn't been needed for a login for too long - or we could even make the code pluggable, since this is a cache eviction problem and there are many different schemes for that, maybe someone knows a better one.
It feels vulnerable to a downgrade attack, but it isn't meaningfully so, because if you didn't have this scheme then you would just have to pick parameters that are secure enough - so just use those parameters as your minimums.
That seems pretty great, but there's a really sucky part to this scheme: both the login experience and the implementation suffer a lot when you are logging in from a much weaker system than any remembered entry. And I don't just mean it would be slow, I mean it might require your Argon2id implementation to handle cases like "every device until now let us use 2GiB of memory and this one's refusing to give us more than 256MiB, so now we have to compute the same result in an eighth of the space".
(Aside: this is a good example of why "limit this program to [amount] memory" is not really the right resource control knob a lot of the time if the implementation is "refuse to let the program address more memory" rather than "use swap space if it tries to have more memory" - code that is willing to give up speed to fit within your memory constraints shouldn't have to reimplement memory page swapping, and if you are not willing to give it that opportunity then that would be a different knob.)
One way to mitigate that sucky edge case:
Since you have an acceptable minimum parameterization of Argon2id anyway, just keep an entry for that permanently.
This is worse in the event of a server compromise than only having stronger parameter entries, but if you didn't have the dynamicism and multiple entries you would still always have this lowest secure parameters entry on the server,
It's still better than just having the lowest parameters in the absence of server secret storage compromise or downgrade attack, because you send a public key and signature corresponding to a private key derived from the password with better parameters.
So I've gone back and forth in my mind about this scheme being worth it or not. There is something really nice about users' password security organically automatically upgrading as their technology upgrades. On the other hand it is very complex, would require a lot of reimplemention of some of the most security-sensitive and "don't write this yourself unless you're a cryptographer and computer security expert!" parts of the system, with more cleverness and complexity than existing implementations.
I think the tie breaker for me is that this is all probably very temporary and maybe already obsolete. The future is not users logging in by typing in passwords that they remember. Asymmetric passwords is a great way to make that better, but that's going away. The future is your device knowing cryptographic keys for each login for you, and maybe one password securing the encrypted secret storage where those keys live.
The recent passkey announcements and standardization was a good reminder of that.
Over a year ago I did some testing and found that 128MiB, 1 lane, and 3 iterations was tolerably slow on some realistically old or weak phones and pretty great on new high-end ones. That's lower than you'd use for server-side password hashing, but I'd rather have the security increase of never sending the password to the server. So you could probably dial that up by approximately a year's worth of typical user technology spec improvement and still get a great login experience range.
That's probably good enough until the passkey stuff takes over entirely.
So if I was to implement asymmetric password logins right now as a learning exercise or proof of concept, I would use Argon2id for key derivation, Ed25519 for signatures, and Ristretto255 for the OPRF.
The thing is, I would really like to get very secure parameters for Argon2id, but even a mere time factor of three with one lane using 256 MiB of RAM costs one to three seconds on recent browser versions on recent hardware with high end specs. That's just for the Argon2id itself.
Of course, if I knew it was making my password resistant to cracking even by state-funded purpose-built ASIC farms, you could make me wait ten seconds to log in and I'd feel pretty good about it. But typical users might start dropping off after half-second delays, and if you can be so responsive that it feels instant, that matters a lot.
Also you could easily create a really nice interface which progressively loads and renders all the UI elements that don't reveal sensitive information while the password verification is happening. If you have an implementation of Argon2id which has hooks or incremental outputs for progress reporting, then you could even accurately and precisely show progress.
So another reason why it's worth carefully looking at OPAQUE is that I'm sure all that stuff it does is actually more performant, much more responsive.
GitHub 支援 SSH 使用 Security Key 了
GitHub 支援 SSH 使用 Security Key 了
GitHub 宣佈支援使用 security key 的 SSH key 操作了:「Security keys are now supported for SSH Git operations」。 也就是需要 SSH key + security key 才有辦法認證,只有拿到 SSH key 或是 security key 都是沒有辦法認證過。 目前官方支援 ecdsa-sk 與 ed25519-sk: Now you can use two additional key types: ecdsa-sk and ed25519-sk, where the “sk” suffix is short for “security key.” 不過在 Ubuntu 20.04 下用預設的系統只能支援 ecdsa-sk,因為 ed25519-sk 會遇到類似「ed25519 problem…
View On WordPress
OpenSSH 8.4 預設停用 ssh-rsa
OpenSSH 8.4 預設停用 ssh-rsa
前幾天 OpenSSH 8.4 釋出了:「Announce: OpenSSH 8.4 released」。
比較重要的改變是 ssh-rsa 預設變成停用,因為是使用 SHA-1 演算法的關係:
It is now possible[1] to perform chosen-prefix attacks against the SHA-1 algorithm for less than USD$50K. For this reason, we will be disabling the “ssh-rsa” public key signature algorithm by default in a near-future release.
官方給了三個方案:
The RFC8332 RSA SHA-2 signature algorithms rsa-sha2-256/512.…
View On WordPress
SSH, algorithms, key formats
SSH, algorithms, key formats
https://en.wikipedia.org/wiki/Secure_Shell
https://en.wikipedia.org/wiki/Ssh-keygen
https://en.wikipedia.org/wiki/Ssh-keygen#Key_formats_supported
View On WordPress
Given SSH pub and priv keys find their length and algorithm
The goal of this post is to show how to get some details about existing OpenSSH keys. To provide a sample it will start off with generating a possibly more secure key as recommended by this excellent blog. As regards whether it is best to move to other algorithms and longer key types Daniel Pocock argues that it may not be necessary. Note also the potential problems with some ssh-agents and interoperability with related infrastructure when moving from RSA 2048 bit to RSA 4096 bit. Note also that the generation example below specifically chooses SSH protocol 2 which is no-PEM compatible.
ssh-keygen -o -a 100 -t ed25519
# From "man ssh-keygen" -o Causes ssh-keygen to save SSH protocol 2 private keys using the new OpenSSH format rather than the more com‐ patible PEM format. The new format has increased resistance to brute-force password cracking but is not sup‐ ported by versions of OpenSSH prior to 6.5. Ed25519 keys always use the new private key format. -a rounds When saving a new-format private key (i.e. an ed25519 key or any SSH protocol 2 key when the -o flag is set), this option specifies the number of KDF (key derivation function) rounds used. Higher numbers result in slower passphrase verification and increased resistance to brute-force password cracking (should the keys be stolen).
Then take a look at the key properties. Can do this with either the public or private key.
ssh-keygen -lf ~/.ssh/id_ed25519.pub 256 40:dd:09:3f:0a:6d:85:4a:33:c9:41:1b:3e:ea:b2:28 ush@testdribble (ED25519)
Note: as of Nov 2016 the OpenSSL suite does not support working with this Edwards twisted-curve function, so we cannot do something like "openssl ed25516 -text -noout -in /path/to/.ssh/ed25519". Patches are being reviewed upstream.
Here's a Mini How-to for openssh with curve25519
Config of /etc/.ssh/ssh_config
Host * IdentityFile ~/.ssh/id_ed25519 IdentityFile ~/.ssh/id_rsa PasswordAuthentication no PubkeyAuthentication yes KexAlgorithms [email protected],diffie-hellman-group-exchange-sha256 Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr MACs [email protected],[email protected],[email protected],[email protected],hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,[email protected] # Github needs diffie-hellman-group-exchange-sha1 some of the time but not always. Host github.com KexAlgorithms [email protected],diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1
At upper level of /etc/.ssh/sshd_config review HostKey settings:
HostKey /etc/ssh/ssh_host_ed25519_key HostKey /etc/ssh/ssh_host_rsa_key
And append the following at the end of config of /etc/.ssh/sshd_config
KexAlgorithms [email protected],diffie-hellman-group-exchange-sha256 Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr MACs [email protected],[email protected],[email protected],[email protected],hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,[email protected]
Then generate a RSA server keys on each site as root
ssh-keygen -t ed25519 -f ssh_host_ed25519_key < /dev/null
Restart openssh-Daemon - /etc/init.d/ssh restart
But please leave a ssh clienct connection open to that ssh site, if there's something wrong with the configuration!
User configuration for each user:
Delete RSA (or DSA) fingerprints of site, which you would like to connect primarily with ED25519 elliptic curves:
ssh-keygen -R hostname
Or just remove all fingerprints:
rm ~/.ssh/known_hosts
Generate a new curve25519 client key:
ssh-keygen -t ed25519 -o -a 100
First ssh connection to each site should look like:
$ ssh host
ED25519 key fingerprint is 00:db:08:ab:ca:ff:0e:11:21:93:b2:ad:37:47:b3:c4:df. Are you sure you want to continue connecting (yes/no)? yes Enter passphrase for key '/home/user/.ssh/id_ed25519':
If all of this doesn't work, maybe you didn't set the appropriate HostKey order: ssh_host_ed25519_key should be at first position at sshd_config!