I am running JDK 1.7 & Windows 7 using netbeans 7.2 I have generated a SSH private & public key pair (SSH2-2048 bits) using putty-keygen. I do not have any password for private key. I am now trying to connect to one of the host machine using SFTP. But when I pass private key (ppk) to set Identity, code is returning invalid private key error. I used same private key in WinSCP to connect to same host & it is working fine. Kindly help me to resolve the error. Here is my code:
JSch jsch = new JSch();
Session session = null;
try {
jsch.addIdentity("D:\\TEMP\\key.ppk");
session = jsch.getSession("tiabscp", "ssiw.support.qvalent.com", 22);
session.setConfig("StrictHostKeyChecking", "no");
//session.setPassword("");
session.connect();
Channel channel = session.openChannel("sftp");
System.out.println("Getting connected");
channel.connect();
System.out.println("connected successfully");
ChannelSftp sftpChannel = (ChannelSftp) channel;
sftpChannel.get("remotefile.txt", "localfile.txt");
sftpChannel.exit();
session.disconnect();
}catch (JSchException e) {
e.printStackTrace();
}catch (SftpException e) {
e.printStackTrace();
}
I guess that your key is not in OpenSSH key file format. JSch expects the private key to be in OpenSSH format.
You can use PuTTYgen to convert your private key to work with OpenSSH by following the steps described here:
- Press Load and select the Private Key that was created with PuTTYgen.
- Enter the passphrase to load the key.
- From the Conversions menu select export OpenSSH key
- Save the private key.
Perhaps not a solution for you, but I found this question when I searched for my issue.
I had accidentally given the path to the public keyfile when JSCH expected the private keyfile.
The following example code may help you.
package ssh.control;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import android.util.Log;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class SSHConnections {
static String user="";
static String pass="";
static String ip="";
static Session session;
public static ChannelExec getChannelExec() throws Exception{
//System.out.println("connected");
//This class serves as a central configuration point, and as a factory for Session objects configured with these settings.
JSch jsch = new JSch();
//A Session represents a connection to a SSH server.
session = jsch.getSession(user, ip, 22);
//getSession() :- the session to which this channel belongs.
session.setPassword(pass);
// Avoid asking for key confirmation
//http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Properties.html
Properties prop = new Properties();
prop.put("StrictHostKeyChecking", "no");
//Sets multiple default configuration options at once.
session.setConfig(prop);
session.connect();
if(session.isConnected()) {
System.out.println("connected");
}
// SSH Channel
//Opens a new channel of some type over this connection.
ChannelExec channelssh = (ChannelExec) session.openChannel("exec");
return channelssh;
}
public static String[] executeRemoteCommand(String command) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ChannelExec channelssh = SSHConnections.getChannelExec();
channelssh.setOutputStream(baos);
// Execute command
channelssh.setCommand(command);//gedit tt
InputStreamReader isr = new InputStreamReader(channelssh.getInputStream());
BufferedReader bufred = new BufferedReader(isr);
channelssh.connect();
String s = bufred.readLine();
List<String> lines = new ArrayList<String>();
int count = 0;
while( s!=null ) {
//System.out.println(s);
lines.add(count,s);
// filesandfolders[count]=s;
// System.out.println(filesandfolders[count]);
s = bufred.readLine();
count++;
}
String filesandfolders[] = new String[count];
for(int i = 0; i<count;i++) {
filesandfolders[i] = lines.get(i);
Log.d("filesandfolders[i]", filesandfolders[i]);
}
//for(int j=0;j<filesandfolders.length;j++) {
//System.out.println(filesandfolders[j]);
//}
//System.out.println("lines is "+lines.get(0));
//int a;
//while((a = isr.read()) != -1)
//System.out.print((char)a);
//channelssh.disconnect();
//return baos.toString();
return filesandfolders;
}
public static List<String> executeRemoteCommand1(String command) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ChannelExec channelssh=SSHConnections.getChannelExec();
channelssh.setOutputStream(baos);
// Execute command
channelssh.setCommand(command);//gedit tt
InputStreamReader isr = new InputStreamReader(channelssh.getInputStream());
BufferedReader bufred = new BufferedReader(isr);
channelssh.connect();
String s = bufred.readLine();
List<String> lines = new ArrayList<String>();
int count=0;
while(s != null) {
//System.out.println(s);
lines.add(count, s);
// filesandfolders[count] = s;
// System.out.println(filesandfolders[count]);
s = bufred.readLine();
count++;
}
String filesandfolders[] = new String[count];
for(int i=0; i<count;i++) {
filesandfolders[i]=lines.get(i);
}
//for(int j=0;j<filesandfolders.length;j++) {
//System.out.println(filesandfolders[j]);
//}
//System.out.println("lines is "+lines.get(0));
//int a;
//while((a = isr.read()) != -1)
//System.out.print((char)a);
//channelssh.disconnect();
//return baos.toString();
return lines;
}
}
To make a directory :
SSHConnections.user = "username";
SSHConnections.ip = "192.168.1.102";
SSHConnections.pass = "mypassword";
ChannelExec channelssh = SSHConnections.getChannelExec();
String dirname = "sampledirectory";
try {
String[] str = SSHConnections.executeRemoteCommand("mkdir "+dirname);
} catch (Exception e) {
e.printStackTrace();
}
You can use PEMWriter to convert your private key to PEM format that will be accepted by JSch
The following example converts a key returned from Java KeyStore (JKS)
Key privateKey = KeyStore.getKey(privateKeyAlias, keyStorePassword);//get key from JKS
StringWriter stringWriter = new StringWriter();
PEMWriter pemWriter = new PEMWriter(stringWriter);
pemWriter.writeObject(privateKey);
pemWriter.close();
byte[] privateKeyPEM = stringWriter.toString().getBytes();
来源:https://stackoverflow.com/questions/15332120/jsch-invalid-private-key