com.jcraft.jsch.JSchException: Auth fail error - jsch

Trying to connect to a host using ssh key auth. Below is my code:
package com.mkyong.common;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
/**
*
*/
public class UserAuthPubKey {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
try {
JSch jsch = new JSch();
String user = "XXXXXXXX";
String host = "XXXXXXXX.XXXXXXX.com";
int port = 22;
String privateKey = "~/.ssh/WF_OPENSSH.ppk";
String passphrase = "XXXXXXXXXXX";
jsch.addIdentity(privateKey,passphrase);
System.out.println("identity added ");
Session session = jsch.getSession(user, host, port);
System.out.println("session created.");
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);
}
}
}
what change should i make here. On debugging the error seems to occur at session.connect(); statement. I am using a private key and a passphrase to connect.

String privateKey = "~/.ssh/WF_OPENSSH.ppk";
Is that a PuTTY-format keyfile? Was it generated from puttygen, the PuTTY key generation utility? Jsch only reads OpenSSH-format key files, not PuTTY-format files.
You can use puttygen to convert the key to OpenSSH format if you want to use that key. See this question.

Get the lastest version of JSch. The old version shows Auth Fail for no reason

Related

Public Key Authentication using j2ssh-maverick-1.5.5.jar

Below is a code snippet for connecting to a remote server using public key authentication. I have generated public and private keys using Putty Key Gen tool and have modified the authorized_keys file in .ssh folder as required. I am able to connect to remote server using Putty and providing the prompted passphrase. I am however not able to connect via the below code. It shows me -
java.io.IOException: The PuTTY key could not be read! Invalid encryption key
Any thoughts around this ?
SocketTransport transport = new SocketTransport(hostname, port);
ssh = con.connect(transport, username);
FileInputStream in;
ByteArrayOutputStream out;
try
{
in = new FileInputStream("E:\\Projects\\RBL\\Finacle Interface\\Finacle\\AuthenticationKeys\\RBLTestPrivateKey.ppk");
out = new ByteArrayOutputStream();
int read;
while((read = in.read()) > -1)
out.write(read);
in.close();
SshPrivateKeyFile pkf = SshPrivateKeyFileFactory.parse(out.toByteArray());
SshKeyPair pair = pkf.toKeyPair("calypso");
PublicKeyAuthentication pk = new PublicKeyAuthentication();
pk.setPrivateKey(pair.getPrivateKey());
pk.setPublicKey(pair.getPublicKey());
if(ssh.authenticate(pk)==SshAuthentication.COMPLETE)
{
Log.info(LOG_CATEGORY, "Authentication completed");
session = ssh.openSessionChannel();
return session;
}
}
catch (IOException | InvalidPassphraseException | SshException e1)
{
e1.printStackTrace();
}
/*PasswordAuthentication pwd = new PasswordAuthentication();
pwd.setPassword(this.password);
if(ssh.authenticate(pwd)==SshAuthentication.COMPLETE)
{
session = ssh.openSessionChannel();
return session;
}*/
}
catch(Exception e)
{
isConnected = false;
e.printStackTrace();
}
If you change your keypair to OpenSSH key(s), it could be work...
SshPrivateKeyFile pkf = SshPrivateKeyFileFactory.parse(new FileInputStream("E:\\Projects\\RBL\\Finacle Interface\\Finacle\\AuthenticationKeys\\TestRBL"));
SshKeyPair pair = pkf.toKeyPair("calypso");
solved my issue

Netty client does not send client certificate during SSL handshake that requires mutual authentication

I'm new to Netty and I try to write an echo server and client that uses mutual authentication. Unfortunately, it's not working, the client doesn't send its client certificate and the server disconnects as expected. Below an overview of what I've done so far and the client side code - that probably contains some bug or I missed something important. Thanks for going through all this!
That is what I have:
Netty version 4.1.0.CR1
Valid keystores, truststores and CRL for download on server
A complete implementation of echo server and client using JSSE directly (that is working as expected)
A working implementation of the echo server using Netty (it's working fine when used with the JSSE based client)
A client based on Netty that does not send a client certificate
Client code:
The channel handler:
package info.junius.tutorial.echo.netty.tls;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;
public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf>
{
#Override
public void channelRead0(ChannelHandlerContext ctx, ByteBuf in)
{
System.out.println("CLIENT: Received echo from server:\n" + in.toString(CharsetUtil.UTF_8));
}
#Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
{
cause.printStackTrace();
ctx.close();
}
}
The channel initialiser:
package info.junius.tutorial.echo.netty.tls;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.handler.ssl.SslContext;
public class ClientChannelInitializer extends ChannelInitializer<Channel>
{
private final SslContext context;
private final String peerHost;
private final int peerPort;
public ClientChannelInitializer(SslContext context, String peerHost, int peerPort)
{
this.context = context;
this.peerHost = peerHost;
this.peerPort = peerPort;
}
#Override
protected void initChannel(Channel channel) throws Exception
{
// Add SSL handler first to encrypt and decrypt everything.
channel.pipeline().addLast(this.context.newHandler(channel.alloc(), this.peerHost, this.peerPort));
// and then business logic.
channel.pipeline().addLast(new EchoClientHandler());
}
}
The echo client:
package info.junius.tutorial.echo.netty.tls;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
public class EchoClient
{
private final String host;
private final int port;
public EchoClient(String host, int port)
{
super();
this.host = host;
this.port = port;
}
public static void main(String[] args) throws Exception
{
if (args.length != 2)
{
System.err.println("Usage: " + EchoClient.class.getSimpleName() + " <host> <port>");
}
else
{
// Security.addProvider(new BouncyCastleProvider());
String host = args[0];
int port = Integer.parseInt(args[1]);
new EchoClient(host, port).start();
}
}
public void start() throws Exception
{
TlsContextUtil tlsContextUtil = new TlsContextUtil();
ChannelInitializer<Channel> channelInitializer = new ClientChannelInitializer(tlsContextUtil.getClientContext(), this.host, this.port);
EventLoopGroup group = new NioEventLoopGroup();
try
{
Bootstrap b = new Bootstrap();
b.group(group).channel(NioSocketChannel.class).handler(channelInitializer);
Channel channel = b.connect(this.host, this.port).sync().channel();
ChannelFuture writeFuture = channel.writeAndFlush("Hello from netty client!\n");
// channel.closeFuture().sync();
writeFuture.sync();
}
finally
{
group.shutdownGracefully().sync();
}
}
}
And a utility class that returns an SslContext:
...
public SslContext getClientContext() throws IOException
{
SslContext sslContext = null;
try
{
// truststore
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX", "SunJSSE");
tmf.init(this.getKeystore(TRUSTSTORE));
// keystore holding client certificate
KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX", "SunJSSE");
kmf.init(this.getKeystore(CLIENT_KEYSTORE), KEYSTORE_PW);
SslContextBuilder builder = SslContextBuilder.forClient().keyManager(kmf).trustManager(tmf).ciphers(PFS_CIPHERS);
// build context
sslContext = builder.build();
}
catch (NoSuchAlgorithmException
| NoSuchProviderException
| KeyStoreException
| IllegalStateException
| UnrecoverableKeyException e)
{
throw new IOException("Unable to create client TLS context", e);
}
return sslContext;
}
...
VM arguments:
-Djavax.net.debug=all -Djava.security.debug="certpath crl" -Dcom.sun.net.ssl.checkRevocation=true -Dcom.sun.security.enableCRLDP=true
I'm quite confident that my mistake must be in the Netty client code, because the system works fine when using JSSE only. Any help is highly appreciated!
Cheers,
Andy
OK, I've got it to work. It was actually my client code that was wrong (the code was based on the secure chat example that comes with Netty). So I changed it to the version used in the echo example:
EchoClientHandler:
#Override
public void channelActive(ChannelHandlerContext ctx)
{
// When notified that the channel is active send a message.
System.out.println("CLIENT: Sending request to server...");
ctx.writeAndFlush(Unpooled.copiedBuffer("Mein Schnitzel ist kaputt!\n", CharsetUtil.UTF_8));
}
and the EchoClient:
try
{
Bootstrap b = new Bootstrap();
b.group(group).channel(NioSocketChannel.class).handler(channelInitializer);
ChannelFuture f = b.connect(this.host, this.port).sync();
f.channel().closeFuture().sync();
}
finally
{
group.shutdownGracefully().sync();
}
The previous code just disconnected too early, so that the handshake never completed.

How to interact with the script after its execution using Jsch

Scenario:
1.I am able to execute a bash script on remote ssh server successfully.
2.The script wants the user to enter some input's to proceed.
The Program hangs after the script is executed.
Q:1 Is this possible using JSCH or any other java based libraries?
Q:2 Which is the best library in java to handle such scenario?
Below is my piece of code :
public class SshMultiCommands
{
public void execute(String u,String h,String p) throws Exception
{
JSch jsch = new JSch();
String user = u;
String host = h;
String passwd = p;
int port = 22;
Session session = jsch.getSession(user, host, port);
session.setPassword(passwd);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
Channel channel = session.openChannel("shell");
OutputStream ops = channel.getOutputStream();
channel.setOutputStream(ops,true);
((ChannelShell)channel).setPtyType("vt102");
((ChannelShell)channel).setEnv("LANG", "ja_JP.eucJP");
PrintStream ps = new PrintStream(channel.getOutputStream());
channel.connect();
Thread.sleep(1000);
InputStream input = channel.getInputStream();
//commands
ps.println("ls -l");
ps.println("bash /opt/dla.sh");
ps.println("3"); // The sample user Input to script.This is getting printed but is not getting executed
printResult(input, channel);
ps.close();
channel.disconnect();
session.disconnect();
//System.out.println("OT Session Completed");
}
private static void printResult(InputStream input,
Channel channel) throws Exception
{
int SIZE = 1024;
byte[] tmp = new byte[SIZE];
while (true)
{
while (input.available() > 0)
{
int i = input.read(tmp, 0, SIZE);
if(i < 0)
break;
System.out.print(new String(tmp, 0, i));
}
if(channel.isClosed())
{
System.out.println("exit-status: " + channel.getExitStatus());
break;
}
try
{
Thread.sleep(300);
}
catch (Exception ee)
{
}
}
}
}
Solution: Put sleep of 5-10 sec after you run the script or program. And keep flushing the output stream after every command. If you already used sleep, extend its time.
The program or script that u run takes a bit of time to take over the system's standard input and out streams. If u pass all the commands and params immediately the parameters which were intented for the program goes to the system's bash instead !

Connect with jsch to a switch using ssh

this is my first time I ask a question here so i dont know how to properly post one, but i will do my best. I have the Jsch library in java but I dont know to connect to the switch using ssh2. How do you but the hostkey of the switch in the session?
my code has something like this...
private static final String user = "admin";
private static final String host = "172.16.13.3";
private static final Integer port = 22;
private static final String pass = "";
public static void main(String[] args) throws Exception{
JSch jsch = new JSch();
Session session = jsch.getSession(user, host, port);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setPassword(pass);
session.connect();
but when its executed the program runs without any errors, but it never connects to the switch.... Thanks for your help!!

SSL Server in Java - javax.net.ssl.SSLException

I am trying to create a server using SSL but I keep getting the following error:
"Server aborted:javax.net.ssl.SSLException: No available certificate or key corresponds to the SSL cipher suites which are enabled."
I am not sure if I am creating the certificates correctly. Here is my code.
I am converting an old TCP Server to an SSL Server
// SSL Server
import java.net.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.net.ServerSocketFactory;
import javax.net.ssl.SSLServerSocketFactory;
public class SSL_Server {
public static void main(String[] args) {
int port = 2018;
ServerSocketFactory ssocketFactory = SSLServerSocketFactory.getDefault();
ServerSocket ssocket = null;
System.out.println("SSL_Server started");
System.setProperty("javax.net.ssl.keyStore","mySrvKeystore");
System.setProperty("javax.net.ssl.keyStorePassword","123456");
final ExecutorService threadPool = Executors.newCachedThreadPool();
try {
ssocket = ssocketFactory.createServerSocket(port);
InetAddress myIP =InetAddress.getLocalHost();
System.out.println(myIP.getHostAddress());
while(true){
Socket aClient = ssocket.accept();
//create a new thread for every client
threadPool.submit(new SSL_ClientHandler(aClient));
}
}
catch(Exception e) {
System.err.println("Server aborted:" + e);
} finally {
try{
ssocket.close();
} catch (Exception e){
System.err.println("could not close connection properly" + e);
}
}
System.out.println("connection was closed successfully");
}
}
System.setProperty("javax.net.ssl. keyStore","mySrvKeystore"); System.setProperty("javax.net.ssl. keyStorePassword","123456");
ServerSocketFactory ssocketFactory = SSLServerSocketFactory.getDefault();
ServerSocket ssocket = null;
System.out.println("SSL_Server started");
You should set the properties that configure the default SSLContext (and thus the default SSLServerSocketFactory) before getting it, since it will configure it then.
System.setProperty("javax.net.ssl.keyStore","mySrvKeystore");
System.setProperty("javax.net.ssl.keyStorePassword","123456");
ServerSocketFactory ssocketFactory = SSLServerSocketFactory.getDefault();
ServerSocket ssocket = null;
System.out.println("SSL_Server started");