jsch ssh connection can't get authorized_keys - java

i'm trying to make a connection via ssh from windows to a unix server
my goal to have it in my java app so i cann run command without inputting passwords on each connect
right now i'm trying to understand what i'm doing wrong with keys
I generated a key in Tectia and uploaded it to server;
I can see it in .ssh as 2798 Apr 17 10:56 authorized_keys
my connection setup looks like this
...
JSch jsch = new JSch();
jsch.setKnownHosts("~/.ssh/know_hosts");
jsch.addIdentity("~/.ssh/authorized_keys");
System.out.println("identity added ");
Session session=jsch.getSession(user, host, 22);
session.setConfig("PreferredAuthentications", "publickey");
System.out.println("session created.");
session.connect();
System.out.println("Connected");
....
and as a result of this i'm getting this error
com.jcraft.jsch.JSchException: java.io.FileNotFoundException:
C:\Users\User\ .ssh\authorized_keys (The system cannot find the path
specified)
it's looking for the key on my local computer and not connecting to the server
what am I going wrong with these keys ?

The argument to addIdentity is a local path to your private key.
Instead, you are giving it a path to a file that:
Would contain a public key;
Does not exit locally anyway.

Related

Java - JSch Disconnected from server despite key pair [duplicate]

I'm running a java program where I transfer a file from one folder to another, using Java SFTP. The problem I'm having is that I'm getting the following error in my Java SFTP (using JSch) :
C:\Oracle\Middleware\Oracle_Home\oracle_common\jdk\bin\javaw.exe
-server -classpath C:\JDeveloper\mywork\Java_Hello_World.adf;C:\JDeveloper\mywork\Java_Hello_World\Client\classes;C:\Users\ADMIN\Downloads\jsch-0.1.53.jar
-Djavax.net.ssl.trustStore=C:\Users\IBM_AD~1\AppData\Local\Temp\trustStore5840796204189742395.jks
FileTransfer com.jcraft.jsch.JSchException: UnknownHostKey: 127.0.0.1.
RSA key fingerprint is a2:39:3f:44:88:e9:1f:d7:d1:71:f4:85:98:fb:90:dc
at com.jcraft.jsch.Session.checkHost(Session.java:797) at
com.jcraft.jsch.Session.connect(Session.java:342) at
com.jcraft.jsch.Session.connect(Session.java:183) at
FileTransfer.main(FileTransfer.java:33) Process exited with exit code
0.
The following is my code so far:
FileTransfer fileTransfer = new FileTransfer();
JSch jsch = new JSch();
try {
String host = "127.0.0.1";
int port = 22;
String user = "user";
Session session = jsch.getSession(user, host, port);
session = jsch.getSession("username", "127.0.0.1", 22);
session.connect(); // bug here , java.net.ConnectException
ChannelSftp sftp = null;
sftp = (ChannelSftp)session.openChannel("sftp") ; //channel;
//extra config code
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
// end extra config code
sftp.rename("C:\\Users\\ADMIN\\Desktop\\Work\\ConnectOne_Bancorp\\Java_Work\\SFTP_1\\house.bmp", "C:\\Users\\ADMIN\\Desktop\\Work\\ConnectOne_Bancorp\\Java_Work\\SFTP_2\\house.bmp");
session.disconnect();
} catch (JSchException e) {
e.printStackTrace();
} catch (SftpException e) {
e.printStackTrace();
} //end-catch
My Cygwin is set up, and I checked (with netstat -a -b ) that it's running.
You are trying to skip a host key checking by setting StrictHostKeyChecking to no.
But you have to do that before the checking, i.e. before the session.connect().
Anyway, you should never do this, unless you do not care about security. The host key checking is there to protect you from man-in-the-middle attacks.
Instead, set up an expected host key to let JSch verify it.
For example:
Call JSch.setKnownHosts providing a path to a .ssh/known_hosts-like file.
To generate the .ssh/known_hosts-like file, you can use an ssh-keyscan command from OpenSSH. If you are connecting from a *nix server, you should have the command available, just run
ssh-keyscan example.com > known_hosts
It will have a format like:
example.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0hVqZOvZ7yWgie9OHdTORJVI5fJJoH1yEGamAd5G3werH0z7e9ybtq1mGUeRkJtea7bzru0ISR0EZ9HIONoGYrDmI7S+BiwpDBUKjva4mAsvzzvsy6Ogy/apkxm6Kbcml8u4wjxaOw3NKzKqeBvR3pc+nQVA+SJUZq8D2XBRd4EDUFXeLzwqwen9G7gSLGB1hJkSuRtGRfOHbLUuCKNR8RV82i3JvlSnAwb3MwN0m3WGdlJA8J+5YAg4e6JgSKrsCObZK7W1R6iuyuH1zA+dtAHyDyYVHB4FnYZPL0hgz2PSb9c+iDEiFcT/lT4/dQ+kRW6DYn66lS8peS8zCJ9CSQ==
And reference the generated known_hosts file in your JSch code.
If you are on Windows, you can get a Windows build of ssh-keyscan from Win32-OpenSSH project or Git for Windows.
Call JSch.getHostKeyRepository().add() to provide the expected host key (e.g. hard-coded, as your other credentials).
See Creating JSch HostKey instance from a public key in .pub format.
jsch version : 0.1.55
my problem solved by running :
ssh-keyscan -t rsa <HOST_NAME> >> ~/.ssh/known_hosts
ssh-keyscan -t rsa <IP_ADDRESS_OF_HOST_NAME> >> ~/.ssh/known_hosts
**in my case jsch was looking for ip address in known_hosts file
jsch.setKnownHosts(System.getProperty("user.home")+"/.ssh/known_hosts");
Aside: by "Cygwin" I assume you mean sshd or sftpd, because Cygwin itself doesn't do SSH.
Anyway, if you want Jsch client to accept any key from the host, move the .setConfig calls that sets StrictHostKeyChecking no so it is before session.connect(). Alternatively you must provide access to a store containing the correct key(s) for your hosts(s) as #Martin explains -- and you should always do that when connecting to anything other than "localhost" or possibly a machine certain to be on the same, physically-secure network segment (such as a wired LAN hub within a single room).

ECDSA key fingerprint Mismatch with Jsch [duplicate]

There are two questions about this exception already:
JSchException: UnknownHostKey and
com.jcraft.jsch.JSchException: UnknownHostKey
I am using a Windows machine and trying to connect to a VM created with Vagrant running Ubuntu. Here is my code:
public static void main(String[] args) {
String host = "localhost";
String username = "vagrant";
int port = 2200;
String privateKey = "C:\\keys\\openSSH_pair1\\open_ssh_private";
JSch js = new JSch();
try {
js.addIdentity(privateKey, "pass");
js.setKnownHosts("C:\\Users\\user\\.ssh\\known_hosts");
Session session = js.getSession(username, host, port);
session.connect();
System.out.println("Connected");
} catch (JSchException e) {
e.printStackTrace();
}
}
#Pascal suggests setting strictHostKeyChecking to no, which works for me, but this is not the preferred solution. His preferred solution is to SSH from the command line so that the host will be added to the known_hosts file. I have Git installed and executed ssh -i openSSH_pair1\open_ssh_private vagrant#localhost -p 2200
and received this output before being prompted for the pass phrase and establishing a connection
The authenticity of host '[localhost]:2200 ([127.0.0.1]:2200)' can't
be established. ECDSA key fingerprint is
11:5d:55:29:8a:77:d8:08:b4:00:9b:a3:61:93:fe:e5. Are you sure you want
to continue connecting (yes/no)? yes Warning: Permanently added
'[localhost]:2200' (ECDSA) to the list of known hosts.
So now my known_hosts file in git_home\.ssh contains an entry for localhost:2200, I also placed the known_hosts file into user_home\.ssh. I also put my private key on the VM I'm trying to ssh into and ran this to generate a public key and add it to the authorized_keys
ssh-keygen -y -f open_ssh_private > open_ssh_gen.pub
cat open_ssh_gen.pub >> ~/.ssh/authorized_keys
However I still get this exception
com.jcraft.jsch.JSchException: UnknownHostKey: localhost. RSA key fingerprint is 50:db:75:ba:11:2f:43:c9:ab:14:40:6d:7f:a1:ee:e3
at com.jcraft.jsch.Session.checkHost(Session.java:797)
at com.jcraft.jsch.Session.connect(Session.java:342)
at com.jcraft.jsch.Session.connect(Session.java:183)
at connect.Main.main(Main.java:24)
The answer to the other question suggests adding the below which doesn't work for me either
js.setKnownHosts("C:\\Users\\user\\.ssh\\known_hosts");
The problem is that you have added ECDSA host key to the known_hosts, as the ssh prefers that key type:
ECDSA key fingerprint is 11:5d:55:29:8a:77:d8:08:b4:00:9b:a3:61:93:fe:e5.
But JSch prefers RSA key, which it won't find in the known_hosts:
RSA key fingerprint is 50:db:75:ba:11:2f:43:c9:ab:14:40:6d:7f:a1:ee:e3
You probably need JCE to enable ECDSA In JSch.
See JSch Algorithm negotiation fail.
Or make ssh use RSA key with -o HostKeyAlgorithms=ssh-rsa.
See How can I force SSH to give an RSA key instead of ECDSA?
You can also use ssh-keyscan:
ssh-keyscan -t rsa example.com

Download SFTP file to Remote server folder directly (not to shared path)

I want to develop a java program to download a file from SFTP server to remote server. That remote server doesn't have any shared path. I have to directly download from sftp and paste in remote windows server driver (D:).
code:
int ftpPort = 22;
JSch jsch = new JSch ();
Session session = null;
Channel channel = null;
ChannelSftp c = null;
try {
session = jsch.getSession(username, hostname, ftpPort);
logger.info("*** FTP Session created. ***");
session.setPassword(password);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
logger.info("*** Session connected. ***");
//Open the SFTP channel
logger.info("*** Opening FTP Channel. ***");
channel = session.openChannel("sftp");
channel.connect();
c = (ChannelSftp) channel;
//Change to the remote directory
logger.info("*** Changing to FTP remote dir: " + remoteDirectory + " ***");
c.cd(remoteDirectory);
//Send the file we generated
try {
logger.info("*** Storing file:'" + filename + "' to local directory: '"+localDirectory+"'");
I am using Jsch and ChannelSftp for connecting to SFTP server.
As of now the above code downloads the code to local path and shared path.
Any suggestion to download the files to Remote server(windows) which doesn't hav any shared path.
Thanks.
Your code would need to run on the remote server directly and download the files from SFTP to its local disk.
Another way would be to download the file on your local machine using your code and then use something like SCP to transfer the file on the remote server, if you really don't have any shared folders.
scp /path/to/your/file user#host:/remote/path
But you said, it's Windows, so you might need to set up SSH/SCP first on that machine.

Folder does not exists when changing directory using jcraft.jsch

I'm running on a Linux machine a Java program that uses jcraft.jsch library to connect to an external sftp server. The code looks like:
JSch jsch = new JSch();
Session session = null;
Channel channel = null;
ChannelSftp c = null;
session = jsch.getSession(ftpUserName, ftpHost, ftpPort);
session.setPassword(ftpPassword);
channel = session.openChannel("sftp");
channel.connect();
c = (ChannelSftp)channel;
fn = c.ls("/Inbox");
c.cd("/Inbox"); //-- this line throws an error
For some reason when I run the change directory command "c.cd" I get:
4: Folder not found: /drwxr-x--- 2 ftpadmin ftpadmin 0 Jan 01 1970 /Inbox
It is weird because the listing (c.ls) of that folder does not throws an exception.
Furthermore, if I lftp from the command line from the same Linux server I can cd without any problems.
The stacktrace points to a _stat method inside the cd method.
at com.jcraft.jsch.ChannelSftp.throwStatusError(ChannelSftp.java:2108)
at com.jcraft.jsch.ChannelSftp._stat(ChannelSftp.java:1676)
at com.jcraft.jsch.ChannelSftp.cd(ChannelSftp.java:290)
at BW_Utilities.ftp.test.testFtpJsch(test.java:81)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
The folder structure of the remote site looks like the following when I connect using Filezilla from my desktop:
I just executed the same Java code on my windows desktop machine and the cd command worked. (Windows machine runs JDK 1.6.0_29 while the Linux server runs JRE 1.6.0.27)
Does jsch relies on some other library at the OS level at the client side?
Any idea how to proceed to troubleshoot this problem?
important UPDATE
I was able to reproduce the error on my dev machine. It got to do with jsch versions being used. The linux server is using jsch-0.1.31 while the dev machine uses jsch-0.1.52. It seems that whatever is causing the error is already solved in version 0.1.52. Wooot! Wooot! Finally!
Thanks
Upgrading to jsch version 0.1.52 fixes the issue.
Try doing the following.
fn = c.ls("Inbox");
c.cd("Inbox");

Copy files from local window machine to remote windows machine using java

I have searched a lot but couldn't get a solution for this. I need to copy a file from local windows machine to remote windows machine using java program. I have tried with JSch,
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("filePath");
//If you want you can change the directory using the following line.
channel.cd("E:/xxx");
channel.put(new FileInputStream(localFile),localFile.getName());
channel.disconnect();
session.disconnect();
While executing the above code, i am facing the below error,
Exception in thread "main" 2: No such file
at com.jcraft.jsch.ChannelSftp.throwStatusError(ChannelSftp.java:2846)
at com.jcraft.jsch.ChannelSftp._realpath(ChannelSftp.java:2340)
at com.jcraft.jsch.ChannelSftp.cd(ChannelSftp.java:342)
I have cygwin installed in remote windows machine. It seems Jsch is not able to find the windows path. The same code works properly when copying files from windows machine to linux machine.
Please tel me a solution for the above problem or is there any other options for this to achieve in java ? Thanks
In order to resolve a Windows path with a drive letter you may need to use the /cygdrive prefix. In this case, your cd method call should be called with the parameter /cygdrive/e/xxx.

Categories

Resources