phpseclib / phpseclib

PHP Secure Communications Library
http://phpseclib.com/
MIT License
5.36k stars 888 forks source link

RSA loadkey does not work with standard keys from ssh-keygen #1372

Open GHLover opened 5 years ago

GHLover commented 5 years ago

Here is the test case:

ssh-keygen -t rsa -b 4096

Accept all defaults and empty password. This will create a key file in:

/home/user/.ssh/id_rsa

Then, to test it with phpseclib:

$key = new phpseclib\Crypt\RSA(); var_dump($key->loadKey(file_get_contents('/home/user/.ssh/id_rsa')));

The result will be "false" key cannot be loaded. It has also been tested with setting a password and then calling the setPassword before loadKey. In either case it does not seem to standard keys.

Is there a way around this? Is there a way to convert standard keys to whatever special format phpseclib requires?

terrafrost commented 5 years ago

Is there a way to convert standard keys to whatever special format phpseclib requires? phpseclib does not make use of any special format.

Does your key start off with any of the following?:

If so then phpseclib supports it. The issue is, in all likelihood, your permissions. If they're not set correctly you'll get an error like this:

WARNING: UNPROTECTED PRIVATE KEY FILE! Permissions 0755 for '/path/to/id_rsa' are too open. It is recommended that your private key files are NOT accessible by others. This private key will be ignored. bad permissions: ignore key: ...

Can you actually see the key if you do echo file_get_contents('/home/user/.ssh/id_rsa')?

bantu commented 5 years ago

Assuming you are using OpenSSH, which version is it?

Necklaces commented 5 years ago
  • -----BEGIN RSA PRIVATE KEY-----
  • -----BEGIN ENCRYPTED PRIVATE KEY-----
  • -----BEGIN PRIVATE KEY-----

I have an openssh private key that starts with -----BEGIN OPENSSH PRIVATE KEY-----, could that be it? My sshd says OpenSSH_8.0p1, OpenSSL 1.1.1c 28 May 2019

Using an RSA key works: ssh-keygen -m PEM -t rsa -b 4096

Edit: Right, so openssh updated its default rsa key format from openssh 7.8 and up: https://community.atlassian.com/t5/Bitbucket-questions/From-OpenSSH-7-8-the-default-format-RSA-key-pair-has-changed/qaq-p/922645

terrafrost commented 5 years ago

That'd explain that.

The master branch supports keys of that format for Ed25519 but encrypted keys in that format are not supported and are unlikely to ever be supported. The following code snippet elaborates:

https://github.com/phpseclib/phpseclib/blob/557676edd9f3130b20b19b7b1a62ee2c5ca4039a/phpseclib/Crypt/ECDSA/Keys/OpenSSH.php#L84-L109

I'll work on adding support for RSA as time permits. I'll prob do it first in the master branch and then the 1.0 / 2.0 branches.

Thanks!

terrafrost commented 5 years ago

https://github.com/phpseclib/phpseclib/commit/327f555b7c9e4c2129d02d112492e8a1b0d233ad adds support for OpenSSH private keys for all key types (RSA, DSA, ECDSA, Ed25519). Tomorrow I'll try to work on backporting the RSA specific stuff to the 1.0 / 2.0 branches.

Thanks!

terrafrost commented 5 years ago

https://github.com/phpseclib/phpseclib/commit/cd7de5723cb171edaeaaaf2337630a3bb121fc3a adds support for OpenSSH private keys for the 1.0 / 2.0 branches. I'll try to do a release in the next few days.

Thanks!

PatrickHuiskens commented 4 years ago

OpenSSH key still doesn't work for me.

What worked for me is converting the OpenSSH key to an RSA key.

ssh-keygen -p -N "" -m pem -f /path/to/key

Make sure to have a backup of your current key, cause this will overwrite it. -N "", will make an empty passphrase.

$sftp = new SFTP('sftp.host.com', 22);
$key   = new RSA();
$key->setPassword('passphrase');
$key->loadKey('get key content here');

This fixed the issue for me.

bantu commented 4 years ago

@PatrickHuiskens What makes it work is the removal of the passphrase. The conversion to PEM format should be irrelevant. As per https://github.com/phpseclib/phpseclib/issues/1372#issuecomment-498657855 encrypted keys of the new format are not supported by phpseclib.

PatrickHuiskens commented 4 years ago

@PatrickHuiskens What makes it work is the removal of the passphrase. The conversion to PEM format should be irrelevant. As per #1372 (comment) encrypted keys of the new format are not supported by phpseclib.

Could be true. But for my own connection I did not remove the passphrase, and it still worked fine.

bluecraank commented 2 years ago

Thanks!!! Ive tried so much and this was the solution. converted openssh encrypted key to rsa private key, still with passphrase and no need to update public key on server. WOW