-
-
Notifications
You must be signed in to change notification settings - Fork 878
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Slow load of a password protected key #1996
Comments
Unfortunately, there's nothing that can really be done about that. The fact that encrypted OpenSSH private keys are supported at all is a small miracle. https://www.reddit.com/r/PHP/comments/vrcypr/my_php_port_of_some_js_code_is_24x_as_slow_as_the/ talks about some of the difficulty of getting them to decrypt in anything resembling a reasonable amount of time. ie. 2.4s is def more time than 0.06s but 2.4s is waaaay better than 24s. To recap the reddit.com post, phpseclib needs a pure-PHP implementation of bcrypt for OpenSSH private keys because (for reasons elaborated in the reddit post) the existing implementations PHP provides aren't suitable, specifically for OpenSSH private keys. As https://security.stackexchange.com/a/150624 elaborates, password hashing algorithms like bcrypt are designed to be slow. The slowness may not be perceptible when you're loading a key with a program implemented in C or assembly or whatever but PHP is neither C or assembly. |
Thanks for clarifiyng that. PHP is written in C, so a better native functionality is needed. Are you aware of any tracked issue in the repo https://github.com/php/php-src? |
No - I've not opened one. It's hard to know where an RFC would be required vs a GitHub issue. I'd also be surprised if anyone has ever requested it because it's pretty niche. Unless you're working with encrypted OpenSSH keys it's not something that'd be all that useful. Prob the best way for php-src to be modified would be to have password_hash modified to accept an additional option for PASSWORD_BCRYPT - basetext or some such. I think that's the only change that'd be needed. It'd prob be best to give me a few days to verify that that is indeed the only needed change before taking any action yourself. |
So it looks like there are other changes that are needed. With normal bcrypt the salt is 16 bytes long. In OpenSSH it's 64 bytes long. So in the pseudo code at https://en.wikipedia.org/wiki/Bcrypt you have this:
OpenSSH is removing the
Whereas Another change: In wikipedia's
OpenSSH does those in reverse order so you'll need to swap the two Yet another change is that OpenSSH switches the endianness of the long (32-bit int)'s. So whereas phpseclib's If the only change were the change from OrpheanBeholderScryDoubt (24 bytes) to OxychromaticBlowfishSwatDynamite (32 bytes) you could make that an optional third parameter to Assuming you made all those changes - and assuming you made
|
So if PHP were to incorporate the OpenSSH method into That said, you wouldn't necessarily need to fork every bcrypt function as https://github.com/openssh/openssh-portable/blob/master/openbsd-compat/bcrypt_pbkdf.c demonstrates. Like in that file the If you wanted to create a bug report or whatever to PHP that'd be cool. I kinda doubt php-src would implement a whole new algorithm just for phpseclib (I can't imagine anyone else really benefiting from such a change) but who knows. |
I also have to say... the fact that OpenSSH made all those changes is kinda obnoxious. It's like they were going for security through obscurity. Like if I wanted to make a secure protocol one approach I could employ would be to make small trivial tweaks to SSH. So let's call this new company Acme Co. Instead of servers identifying themselves as SSH-2.0-whatever they could identify themselves as ACME-1.0. And instead of running on port 22 they could run on port 54134. And instead of using little endian or whatever endianness they use the opposite endianness. And whamo, nmap is now not going to find the server and metasploit exploits won't be able to run on it! Woo hoo! Security through obscurity at the expense of interoperability. Also unhelpful is the fact that altho https://github.com/openssh/openssh-portable/blob/master/openbsd-compat/bcrypt_pbkdf.c mentions some of these changes it does not mention all of them. |
Got it. Hope that this issue at least was useful for documenting all the difficulties in decrypting openSSH keys. |
It seems that unencrypting a password protected key is very slow. The same key, if not password protected is super fast to load. I've also tried to be as specific as possible in the loading, but I gained just a few milliseconds. The login method works fine and it is very fast.
I use PHP8.3, library 3.0.37 and all extensions are enabled (GMP, libsodium, DOM, openSSL). I use, for now, only ed25519 keys generated with openSSH.
Slow code (around ~2.4s):
Fast code (around ~0.06s):
I've read several issues here before posting, but I was not able to find a similar one.
The text was updated successfully, but these errors were encountered: