This question already has an answer here:
Can we use JSch for SSH key-based communication?
(1 answer)
Closed 4 years ago.
I have two servers A and B.
I want to SFTP a file from server A to B.
Public key of server A (~/.ssh/id_rsa.pub) has been added to the ~/.ssh/authorized_keys of server B.
From command line, I can SFTP from server A to B without entering password.
However, from a Java client using library Jsch I am unable to make SFTP connection to server B and I am getting authentication error:
Error occurred during SFTP. Auth fail
com.jcraft.jsch.JSchException: Auth fail
at com.jcraft.jsch.Session.connect(Session.java:519)
at com.jcraft.jsch.Session.connect(Session.java:183)
at Main.main(Main.java:15)
Is there a way I can connect to server B for SFTP purposes using Java client without specifying password?
Below is my Java code for reference:
import com.jcraft.jsch.*;
public class Main {
public static void main(String[] args) {
JSch jsch = new JSch();
Session session = null;
try {
session = jsch.getSession("processor", "remoteserver.myorg.com", 22);
session.setConfig("StrictHostKeyChecking", "no");
System.out.println("Trying to connect...");
session.connect();
System.out.println("Connected successfully.");
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
System.out.println("Doing SFTP...");
sftpChannel.put("/tmp/test.txt", "/some/remote/folder");
System.out.println("Success");
sftpChannel.exit();
session.disconnect();
} catch (JSchException | SftpException e) {
System.err.println("Error occurred during SFTP. " + e.getMessage());
e.printStackTrace();
}
}
}
Use addIdentity() api in jsync and point to your private key file location.
Ref:
Can we use JSch for SSH key-based communication?
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.");
Related
I try to connect SFTP Server using Jsch Library. It works when i use username/password, but with private/public key does not work. i have been read all questions about this theme in Stackoverflow and in other Site webs, but i did not find what i search for.
To test my private key, i have used Terminal(also WinSCP), it works fine, but with Java Code i get this " Auth fail"
This is an Example:
public static void main(String[] args) throws JSchException, SftpException, IOException {
JSch jsch = new JSch();
Properties config=new Properties();
config.put("StrictHostKeyChecking", "no");
jsch.addIdentity("path_to_private_key");
Session session;
session = jsch.getSession("user", "host", 22);
session.setConfig(config);
// session.setPassword("pass");
session.connect();
System.out.println("CONNECT !!! ");
session.disconnect();
}
. I have generated keys using this command: ssh-keygen -C "" -m PEM id_rsa
. past public key in /.ssh/authorized_keys
Any help please?
I have functionality (Java 8 app) to read files from FTP by Apache Commons
FTPClient ftp = new FTPClient();
ftp.connect(
FtpProperties.getHost(),
FtpProperties.getPort()
);
boolean login = ftp.login(
FtpProperties.getUname(),
FtpProperties.getPass()
);
ftp.enterLocalPassiveMode();
ftp.changeWorkingDirectory("/files");
FTPFile[] files = ftp.listFiles();
Files are not explicitly saved locally anywhere. I download to the files[] by ftp.listFiles(). In my files[] i have of all files from ftp directtory. And I can display them normally, save them, do whatever I want with them.
Does anyone know of an analogous solution for SFTP ?
SOLUTION:
public static void ls() throws Exception {
JSch jsch = new JSch();
Session session = jsch.getSession("user", "host", port);
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword("password");
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
Vector<ChannelSftp.LsEntry> returnVector = sftpChannel.ls("/files");
List<String> returnList = new ArrayList<>();
for (ChannelSftp.LsEntry item : returnVector) {
returnList.add(item.getFilename());
}
System.out.println(returnList);
}
System.out.println(returnList); result in console:
[myfile.txt]
This is it what i wanted to achieve. Thanks Rob !
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.
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);
}
}
}
I'm trying to use JSch in Java to connect to one of my EC2 instances, but keep getting an "UnknownHostKey" exception message. Here's is (part of) my code:
import com.jcraft.jsch.*;
import java.io.*;
public class JSchTest {
private String serverIp;
public void testSshConnection() {
try {
JSch jsch = new JSch();
jsch.addIdentity("C:\\Users\\Administrator\\.ssh\\id_rsa");
Session session = jsch.getSession("ec2-user", serverIp, 22);
session.connect(30000); // <-- this is where the exception is thrown
ChannelExec channel = (ChannelExec)session.openChannel("shell");
// more code here...
channel.disconnect();
session.disconnect();
} catch (JSchException|IOException ex) {
ex.printStackTrace();
}
}
public void setServerIp(String serverIp) {
this.serverIp = serverIp;
}
}
I've already added my public key to the authorized_keys file on the EC2 instance that I'm connecting to, and I know it works because I can connect to it using PuTTY. However as soon as I hit the line with the session.connect() in it, I get an exception like this:
com.jcraft.jsch.JSchException: UnknownHostKey: 10.114.2.115. RSA key fingerprint is 63:04:cf:60:4a:1d:47:35:12:0e:56:4f:5b:0a:c9:d4
What am I missing? How can I get this to connect?
Try this:
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
As per this link.
I wants to write a program to copy/create one file from linux machine to another linux/windows machine in java.
I tried below code,which will create one file in another windows machine..
import java.io.File;
import java.io.IOException;
public class Example2 {
public static void main(String[] args) {
String path = "\\\\10.15.0.166"+File.separator+"test";
String fname= path+File.separator+"Sample.pdf";
File file = new File(fname);
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Exists"+file.exists());
file.getParentFile().mkdirs();
}
}
It worked in WIndows to windows.
But when I tried from linux machine .it is creating folder in the linux machine itself.
Could any one help me to solve this?
To work the above application ,We have to add one more line in the above code,
session.put("StrictHostKeyChecking", "no"); just before session.connect();
Complete program is
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import java.io.File;
public class test {
public static void main(String args[]) throws JSchException {
JSch jsch = new JSch();
Session session = jsch.getSession("user", "10.15.0.243", 22); //port is usually 22
session.setPassword("password1.");
session.put("StrictHostKeyChecking", "no");
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp cFTP = (ChannelSftp) channel;
jsch.setConfig("StrictHostKeyChecking", "no");
String sourceFile = "/home/divya/hi.txt", targetFile = "/home/user/test";
try {
cFTP.put(sourceFile , targetFile );
} catch (SftpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
cFTP.disconnect();
session.disconnect();
}
}
Regards
Divya
You should use something like FTP to move files between unix machines.
JSCH is a good API for that.
You will need some user authentication tho.
Here is an example:
JSch jsch = new JSCH();
Session session = jsch.getSession(config.getUsername(), config.getHostname(), config.getPort()); //port is usually 22
session.setPassword(config.getPassword());
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp cFTP = (ChannelSftp) channel;
String sourceFile = "---", targetFile = "---";
cFTP.put(sourceFile , targetFile );
cFTP.disconnect();
session.disconnect();
You can't create a file on another machine this way under Linux... You are using Windows share folders, which is not the way files are shared in Linux world. You have two choices :
either by connecting the two filesystems, with NFS for example (a
kind of Unix file sharing), in such a way that the second filesystem
is mounted on the first one so that a path will lead you to the
second machine in a way similar to Windows file sharing paths.
either by using some protocol to transfer your file (FTP, RSYNC,
etc).
You can use this code snippet to copy files to another linux machine.
JSch jsch = new JSch();
Session session = null;
session = jsch.getSession("username","hostname",22);
session.setPassword("password");
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
ChannelSftp channel = null;
channel = (ChannelSftp)session.openChannel("sftp");
channel.connect();
File localFile = new File("localfilepath");
//If you want you can change the directory using the following line.
channel.cd(RemoteDirectoryPath)
channel.put(new FileInputStream(localFile),localFile.getName());
channel.disconnect();
session.disconnect();
For more details reach out THIS similar post