Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connect to SFTP using PHP and private key

Tags:

php

sftp

libssh2

I have read article after article and just cannot find "the solution" that works for what I have.

I am trying to upload files via SFTP using php scripting. I have connected using CyberDuck successfully, but I need to do this programatically.

I have a .PPK file from the vendor that I used in CyberDuck. I have a username. I have the hostname. If I open the PPK file I see some Public Lines, Private Lines and Private-MAC.

Is there anyway I can access the server to do what I need to do using the information I have?

Here is the code I was playing with:

<?php if (!function_exists("ssh2_connect")) die("function ssh2_connect doesn't exist");
?>
<?php
$conn = ssh2_connect('hostname.com', 22);
echo $conn;
ssh2_auth_pubkey_file($conn,'USERNAME','/var/www/html/FILENAME.PPK');

// send a file
ssh2_scp_send($conn, '/var/www/html/FILETOSEND.TXT', 'FILETOSEND.TXT', 0644);
?>

I don't receive any errors but the file doesn't show up on the server. I can confirm that SSH2 is installed on my webhost.

Thanks for any help you can provide.

like image 401
Joey Martin Avatar asked Jan 31 '15 21:01

Joey Martin


People also ask

How do I use a private key to login to SFTP server?

In your system tray, you'll see the Pageant icon appear. Right-click the icon and select “Add Key” and select your private key (PPK) file. Follow the prompt to enter your pass phrase and you're done. Now simply launch FileZilla Pro and connect to your server using SFTP using SSH2 with a username and an empty password.

How does public and private key work in SFTP?

The user's Public & Private Keys are a pair of keys used to authenticate a client when it connects to an SFTP server. The user's private key is kept secret and stored locally on the user's PC while the user's public key is uploaded and registered on the SFTP server the user connects to.


2 Answers

The question is quite old, but as I was looking for exactly the same answer, here is what I managed to gather.

First: Change key format from .ppk to .pem

.pkk keys are PuTTY format private key.

If you want to change that to .pem format, you need to install putty-tools with:

sudo apt install putty-tools

(On a Mac, install putty package with homebrew. For Windows, I have no clue.)

Then you can change the format of the key:

puttygen privatekey.ppk -O private-openssh -o privatekey.pem

Just in case you want to extract the public key from that private key, (you won't need for the rest of that answer, but just in case) it is quite easy:

openssl rsa -in privatekey.pem -pubout > publickey.pub

Second: Login with sFTP

Now that you have the privatekey.pem, you can use phpseclib to connect via SFTP. First, install phpseclib with Composer:

composer require phpseclib/phpseclib

Then in PHP:

require "vendor/autoload.php";

use phpseclib\Crypt\RSA;
use phpseclib\Net\SFTP;

$sftp = new SFTP('sftp.server.com');

// create new RSA key
$privateKey = new RSA();

// in case that key has a password
$privateKey->setPassword('private key password');

// load the private key
$privateKey->loadKey(file_get_contents('/path/to/privatekey.pem'));

// login via sftp
if (!$sftp->login('username', $privateKey)) {
    throw new Exception('sFTP login failed');
}

// now you can list what's in here
$filesAndFolders = $sftp->nlist();

// you can change directory
$sftp->chdir('coolstuffdir');

// get a file
$sftp->get('remoteFile', 'localFile');

// create a remote new file with defined content
$sftp->put('newfile.txt', 'new file content');

// put a local file
$sftp->put('remote.txt', 'local.txt', NET_SFTP_LOCAL_FILE);

If you want more info, go to the phpseclib sFTP feature list.

like image 86
Stéphane Le Solliec Avatar answered Sep 21 '22 23:09

Stéphane Le Solliec


if i may share my findings based on the code sample answered by Stéphane Le Solliec, you guys have to check your phpseclib version. to check the phpseclib version by composer (windows), you just have to type in the command prompt composer require phpseclib/phpseclib, the result will show the version if installed.

If the phpseclib version is 1.0, i suggest that you modify the line $sftp = new SFTP('sftp.server.com'); into $sftp = new NET_SFTP('sftp.server.com');

If the phpseclib version is 2.0, i suggest that you modify the line $sftp->put('remote.txt', 'local.txt', NET_SFTP_LOCAL_FILE); into $sftp->put('remote.txt', 'local.txt', SFTP::SOURCE_LOCAL_FILE);.

Thank you.

like image 26
Aslam Faisal Avatar answered Sep 23 '22 23:09

Aslam Faisal