Public Key Authentication using j2ssh-maverick-1.5.5.jar - authentication

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

Related

SSL connectivity to Redis with StackExchange.Redis

I am having a very weird issue with StackExchange.Redis to connect with Redis.
I have enabled SSL on Redis database and I am not able to connect from client to Redis server with SSL certificate with below code.
static RedisConnectionFactory()
{
try
{
string connectionString = "rediscluster:13184";
var options = ConfigurationOptions.Parse(connectionString);
options.Password = "PASSWORD";
options.AllowAdmin = true;
options.AbortOnConnectFail = false;
options.Ssl = true;
options.SslHost = "HOSTNAME";
var certificate = GetCertificateFromThubprint();
options.CertificateSelection += delegate
{
return certificate;
};
Connection = new Lazy<ConnectionMultiplexer>(
() => ConnectionMultiplexer.Connect(options)
);
}
catch (Exception ex)
{
throw new Exception("Unable to connect to Cache Server " + ex);
}
}
public static ConnectionMultiplexer GetConnection() => Connection.Value;
public static IEnumerable<RedisKey> GetCacheKeys()
{
return GetConnection().GetServer("rediscluster", 13184).Keys();
}
// Find certificate based on Thumbprint
private static X509Certificate2 GetCertificateFromThubprint()
{
// Find certificate from "certificate store" based on thumbprint and return
StoreName CertStoreName = StoreName.Root;
string PFXThumbPrint = "NUMBER";
X509Store certLocalMachineStore = new X509Store(CertStoreName, StoreLocation.LocalMachine);
certLocalMachineStore.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certLocalMachineCollection = certLocalMachineStore.Certificates.Find(
X509FindType.FindByThumbprint, PFXThumbPrint, true);
certLocalMachineStore.Close();
return certLocalMachineCollection[0];
}
However, If I create a console application and connect to Redis with above code then I am able to connect, but If I used same code from my web application to connect to redis then I am not able to connect.
Not sure if I am missing something.
Also, I went through "mgravell" post
In that post he has configured "CertificateValidation" method, In my scenario I want Redis to validate SSL certificate. so I have not implementation validation. And implemented "CertificateSelection" method to provide client certificate.
You can try to validate the cert using CertificateValidation. I tried the following code and it worked for me:
options.CertificateValidation += ValidateServerCertificate;
...
public static bool ValidateServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
return false;
}
In cases like this where you are using a client certificate and it works in a console app but does not work for some other application (you don't say but I guess from an IIS hosted web app), it almost always has to do with whether the account has permission to access the private key.
The console app runs with your account which probably has access to the private key.
To give an account access
open the Local Computer certificate store
find your client certificate
right click and choose "All tasks -> Manage Provate Keys..."
click "Add..." and add the account.
Note: if your adding an IIS App Pool account the format is:
IIS APPPOOL<my app pool name>
Location should be the local machine and not a domain.
I was able to ssl the Redis server I had started on a VM with the following codes.
add stackexchange.redis visual studio
try
{
ConfigurationOptions configurationOptions = new ConfigurationOptions
{
KeepAlive = 0,
AllowAdmin = true,
EndPoints = { { "SERVER IP ADDRESS", 6379 }, { "127.0.0.1", 6379 } },
ConnectTimeout = 5000,
ConnectRetry = 5,
SyncTimeout = 5000,
AbortOnConnectFail = false,
};
configurationOptions.CertificateSelection += delegate
{
var cert = new X509Certificate2("PFX FILE PATH", "");
return cert;
};
ConnectionMultiplexer connection =
ConnectionMultiplexer.Connect(configurationOptions);
IDatabase databaseCache = connection.GetDatabase();
//set value
databaseCache.StringSet("KEYNAME", "KEYVALUE");
//get Value
label_show_value.Text = databaseCache.StringGet("KEYNAME").ToString();
}
catch (Exception e1)
{
}

download a certificate from a ldap server in java

Can someone explain to me whether following code is correct to download a certificate ties to a specific person in java? I am getting an exception as "unknown protocol: ldaps".
public void downloadCert() {
String urlStr="ldaps://aServerSomeWhere:636/cn=doe%20john,ou=personnel,o=comany123,c=us?caCertificate;binary";
URL url = null;
try {
url = new URL(urlStr);
URLConnection con = url.openConnection();
InputStream is = con.getInputStream();
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate)certFactory.generateCertificate(is);
System.out.println("getVersion: " + cert.getVersion());
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
No it isn't correct. There is no handler for the LDAPS: protocol in the URL/URLConnection system.
You can use JNDI to get the caCertificate attribute of that user, via DirContext.getAttributes().

com.jcraft.jsch.JSchException: Auth fail error

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

Fail to upload file using FTPClient

I have to upload and download a file using FTP server but I am facing issues in it. Have gone though many solutions but nothing seems to be working.
I am using secureftp-test.com as the testing FTP server.
Below is the code for uploading where in I am using FTPClient storeFile method but it doesn't seems to work.
public static void main(String[] args) {
String server = "ftp.secureftp-test.com";
int port = 21;
String user = "test";
String pass = "test";
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect(server, port);
boolean login = ftpClient.login(user, pass);
System.out.println("login " + login);
ftpClient.setFileTransferMode(FTP.BINARY_FILE_TYPE);
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
File firstLocalFile = new File("D:/jetty.pdf");
String firstRemoteFile = "myfile.pdf";
InputStream inputStream = new FileInputStream(firstLocalFile);
System.out.println("Start uploading first file");
boolean done = ftpClient.storeFile(firstRemoteFile, inputStream);
inputStream.close();
if (done) {
System.out.println("The first file is uploaded successfully.");
} else {
System.out.println("upload failed");
}
} catch (IOException ex) {
System.out.println("Error: " + ex.getMessage());
ex.printStackTrace();
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Each time the output is "upload failed". I don't understand where i am wrong.
Your port is incorrect. It uses:
FTPS via Auth TLS/SSL and implicit FTP over SSL on port 990
Also, if you read the site carefully, upload is forbidden:
Chilkat provides this FTPS test account for anyone wishing to test secure FTP client functionality. You may connect to ftp.secureftp-test.com, login as "test" with password "test", and download any files present on the server. The "test" account may also retrieve directory listings. However, it is restricted from uploading files to the server.
Reference: secureftp-test.com

JGit clone repository

I'm trying to clone Git repository with JGit and I have problem with UnsupportedCredentialItem.
My code:
FileRepositoryBuilder builder = new FileRepositoryBuilder();
Repository repository = builder.setGitDir(PATH).readEnvironment().findGitDir().build();
Git git = new Git(repository);
CloneCommand clone = git.cloneRepository();
clone.setBare(false);
clone.setCloneAllBranches(true);
clone.setDirectory(PATH).setURI(url);
UsernamePasswordCredentialsProvider user = new UsernamePasswordCredentialsProvider(login, password);
clone.setCredentialsProvider(user);
clone.call();
It will occur Exception:
org.eclipse.jgit.errors.UnsupportedCredentialItem: ssh://git#github.com:22: Passphrase for C:\Users\Marek\.ssh\id_rsa at
org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider.get(UsernamePasswordCredentialsProvider.java:110)....
But if I delete file known_hosts in .ssh\ It will occur different Exception
org.eclipse.jgit.errors.UnsupportedCredentialItem: ssh://git#github.com:22: The authenticity of host 'github.com' can't be established.
RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
Are you sure you want to continue connecting?
at org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider.get(UsernamePasswordCredentialsProvider.java:110)....
Is there any possibility to type "yes" to that question or just skip it?
Thank you!
I think if you login with username and password, you need https. For ssh you will need a public key that matches the one on record with github.
This will do it (like #michals, only less code) if using username / password with ssh
public void gitClone() throws GitAPIException {
final File localPath = new File("./TestRepo");
Git.cloneRepository()
.setURI(REMOTE_URL)
.setDirectory(localPath)
.setCredentialsProvider(new UsernamePasswordCredentialsProvider("***", "***"))
.call();
}
I suppose you would want to check the github help:
http://help.github.com/win-set-up-git/
Especially the part about generating ssh keys (ssh-keygen -t rsa -C "your_email#youremail.com"). Read the article for your environment, and you'll understand how to get a better configuration.
I had the same problem. The reason was passphrase set for rsa private key. When I remove passphrase for this key it started work without any CredentialsProvider.
UsernamePasswordCredentialsProvider probably don't support passphrase. If you would like to have passphrase set, you could define you own CredentialProvider, which will support it, for example:
CloneCommand clone = Git.cloneRepository()
.setURI("...")
.setCredentialsProvider(new CredentialsProvider() {
#Override
public boolean supports(CredentialItem... items) {
return true;
}
#Override
public boolean isInteractive() {
return true;
}
#Override
public boolean get(URIish uri, CredentialItem... items)
throws UnsupportedCredentialItem {
for (CredentialItem item : items) {
if (item instanceof CredentialItem.StringType) {
((CredentialItem.StringType) item).
setValue(new String("YOUR_PASSPHRASE"));
continue;
}
}
return true;
}
});
clone.call();
It works for me ;)
I had a similar issue, though my setup was a bit different. Leaving this here in case anyone else encounters something similar. I had overridden my configure method and createDefaultJSch method according to this tutorial: https://www.codeaffine.com/2014/12/09/jgit-authentication/
I had something like:
#Override
public void configure( Transport transport ) {
SshTransport sshTransport = ( SshTransport )transport;
sshTransport.setSshSessionFactory( sshSessionFactory );
}
#Override
protected JSch createDefaultJSch( FS fs ) throws JSchException {
JSch defaultJSch = super.createDefaultJSch( fs );
defaultJSch.addIdentity( "/path/to/private_key" );
return defaultJSch;
}
I ended up changing my createdDefaultJSch method to getSch (adding the appropriate parameters) and adding removeAllIdentity():
#Override
public JSch getJSch(final OpenSshConfig.Host hc, FS fs) throws JSchException {
JSch jSch = super.getJSch(hc, fs)
jSch.removeAllIdentity()
jSch.addIdentity( "/path/to/private_key" )
return jSch
}
No idea why this worked, but I found the getSch thing from this answer (coincidentally by the same guy who wrote the tutorial): Using Keys with JGit to Access a Git Repository Securely
It is not clear to me whether you want to do username/password authentication or public/private key authentication. Either way, CredentialsProvider will not be used, according to this. You need to configure the transport. First, create a transport configuration callback:
SshSessionFactory sshSessionFactory = new JschConfigSessionFactory() {
#Override
protected void configure( Host host, Session session ) {
// If you are using username/password authentication, add the following line
session.setPassword( "password" );
}
} );
TransportConfigCallback transportConfigCallback = new TransportConfigCallback() {
#Override
public void configure( Transport transport ) {
SshTransport sshTransport = ( SshTransport )transport;
sshTransport.setSshSessionFactory( sshSessionFactory );
}
};
Then configure the command with it:
clone.setTransportConfigCallback( transportConfigCallback );
If the repository is private and needs authentication, you(#Scruger) will do it using username/password with ssh for clone repository.
private UsernamePasswordCredentialsProvider configAuthentication(String user, String password) {
return new UsernamePasswordCredentialsProvider(user, password );
}
public void clonneRepositoryWithAuthentication(String link, String directory,String branch,String user, String password){
System.out.println("cloning repository private from bitcketebuk");
try {
Git.cloneRepository()//function responsible to clone repository
.setURI(link)// set link to repository git
.setDirectory(new File(Constants.PATH_DEFAULT + directory))//Defined the path local the cloning
.setCredentialsProvider(configAuthentication(user, password))
.setCloneAllBranches(true)//Defined clone all branch exists on repository
.call();//execute call the clone repository git
System.out.println("Cloning sucess.....");
} catch (GitAPIException e) {
System.err.println("Error Cloning repository " + link + " : "+ e.getMessage());
}
}