57

I am using JSch for sftp communication, now i want to use facilitate the key-based authentication, key is loaded on client and server machine once by my network team and all later communication would be only user based for which we have loaded the key.

sftp -oPort=10022 jmark@192.18.0.246

as tjill@192.18.0.135

like this command work fine and connect to the sftp, how i can achieve this functionality programmatically.

if it is not possible using JSch, please suggest some other library. I came across Apache SSHD.

casperOne
  • 72,334
  • 18
  • 180
  • 242
Ahmad Nadeem
  • 1,917
  • 1
  • 17
  • 19

1 Answers1

113

It is possible. Have a look at JSch.addIdentity(...)

This allows you to use key either as byte array or to read it from file.

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

public class UserAuthPubKey {
    public static void main(String[] arg) {
        try {
            JSch jsch = new JSch();

            String user = "tjill";
            String host = "192.18.0.246";
            int port = 10022;
            String privateKey = ".ssh/id_rsa";

            jsch.addIdentity(privateKey);
            System.out.println("identity added ");

            Session session = jsch.getSession(user, host, port);
            System.out.println("session created.");

            // disabling StrictHostKeyChecking may help to make connection but makes it insecure
            // see http://stackoverflow.com/questions/30178936/jsch-sftp-security-with-session-setconfigstricthostkeychecking-no
            // 
            // java.util.Properties config = new java.util.Properties();
            // config.put("StrictHostKeyChecking", "no");
            // session.setConfig(config);

            session.connect();
            System.out.println("session connected.....");

            Channel channel = session.openChannel("sftp");
            channel.setInputStream(System.in);
            channel.setOutputStream(System.out);
            channel.connect();
            System.out.println("shell channel connected....");

            ChannelSftp c = (ChannelSftp) channel;

            String fileName = "test.txt";
            c.put(fileName, "./in/");
            c.exit();
            System.out.println("done");

        } catch (Exception e) {
            System.err.println(e);
        }
    }
}
Arnost Valicek
  • 2,298
  • 1
  • 17
  • 14
  • actually I do not have any key, it is pre loaded in the system by the network team, and now i can connect to the server using the command without the key or the password. – Ahmad Nadeem Feb 08 '11 at 11:37
  • 1
    *Preloaded in the system* may mean it is `.ssh/id_rsa` or similar, or that there is a special setting in `.ssh/config` for your host, or that you are using some program like `ssh_agent` to give the key on demand. Explore which is the case for you, and add it to your question. – Paŭlo Ebermann Feb 08 '11 at 11:52
  • 5
    In my case I needed to provide UserInfo as well: `session.setUserInfo(userinfo)`. Without it I was getting `JSchException: USERAUTH fail` – pavel_kazlou Dec 03 '12 at 08:17
  • I had same problem, I have no idea why it needs login name when I used private key :-/ On the other hand I'm not sure when I use `ssh -i /path/to/private_key` if it sends username or not... – Betlista Dec 03 '12 at 16:18
  • 2
    @Betlista When you use `ssh -i`, without specifying a username, it uses the username of the account on the client machine. So, if you're logged in as steve@client, it's like saying `ssh -i /path/to/private_key steve@remote`. – Alex Mar 16 '13 at 21:24
  • Please do not suggest anyone to set `StrictHostKeyChecking`. At least not without explaining the consequences! See for example [JSch SFTP security with session.setConfig(“StrictHostKeyChecking”, “no”);](http://stackoverflow.com/q/30178936/850848). – Martin Prikryl Sep 11 '15 at 05:47
  • 1
    @Martin - I updated code example with link to you SO answer. It should be clear now that disabling StrictHostKeyChecking is insecure. – Arnost Valicek Sep 11 '15 at 06:43
  • 1
    Just to add: There is also an `addIdentity()` method which accepts the key and the passphrase for it, so you don't need to handle an `UserInfo`-Object – bish Oct 25 '17 at 07:39
  • How can I get the user name ? how can I get the id_rsa file ? Actually I am trying to run the command `ssh -R 80:localhost:8080 serveo.net` from a android device ? @ArnostValicek – Mithun Sarker Shuvro Jul 02 '20 at 18:24
  • What is the use of `addIdentity()` function having the public key option? What is the use of public key in this context? Private key is more than enough to ssh into the host. – piepi Jul 26 '21 at 10:18
  • the `addIndentity()` function only accepts a PEM format key (beginning with `-----BEGIN RSA PRIVATE KEY-----`). Is there a way to use OPENSSH format (beginning with `-----BEGIN OPENSSH PRIVATE KEY-----`)? – skrisshnaswamy May 11 '22 at 10:04