JSch: Checking a private key file passphrase before trying to connect - ssh

For quite a simple application that mostly depends on ssh connections made via JSch, I wanted to ask for the passphrase at the login screen, try to decrypt the private key and if it is wrong, go back to the login window.
I could not find the way to discover whether an invocation to
jsch.addIdentity(keyfile, prvkey, pubkey, passphrase);
ended properly, even if I can see in the code that the decryption has already been tried, and I suppose it already knows the passphrase is wrong.
Is there any way to detect the passphrase is correct BEFORE attempting to establish any session?
Thank you.

You can use KeyPair class for your requirements as follows,
KeyPair kpair = KeyPair.load(jsch, prvkey, pubkey);
System.out.println(kpair.decrypt(passphrase));

Related

GPG authentication subkey: "invalid format" error

I've been using GPG with authentication subkeys for a while now, and I recently ran into a rather unhelpful error message. I'm writing this question "Q&A-style" to help others who might run into the same problem.
I use a set of GPG keys for GitHub stuff — both for commit signing and for authentication via SSH. I decided to upgrade the authentication subkey to the newer ED25519 elliptic curve standard, so I added a new ed25519 subkey with authentication capability and revoked the old RSA authentication subkey. I gpg --export-ssh-keyed the new subkey, then added it to both GitHub and a local ~/.ssh/id_gpg_gh.pub file, which is set as my identity file for GitHub via my SSH config.
At this point, though, SSH threw a Load key ".ssh/id_gpg_gh.pub": invalid format error when I tested my login ability. Connecting in verbose mode (ssh -T github.com -v) revealed that SSH was correctly advertising my new key and GitHub was accepting it, but that acceptance was immediately followed by the error message. It seemed that SSH was refusing to actually use my new subkey due to formatting issues.
The error message in this case turned out to be a bit misleading. There was no formatting error in my public key file, as it suggested. Instead, I'd forgotten to tell the GPG agent to use my new subkey, which I fixed by adding its keygrip to ~/.gnupg/sshcontrol.
Despite this being a simple fix, the error message was misleading enough that I anticipate others running into the same issue and being similarly confused. I hope this answer will be useful in such a case.
Also, in case anyone reading this needs a good reference for setting up GPG/SSH authentication in the first place: there are several guides available online, but this one from opensource.com is a good one to start with. This was also how I identified the setup step that I'd skipped, solving my issue.

Use PGP Keypair for login

I created a PGP master key and an authenticate subkey on my Ubuntu server. For a user testUserX, which I still have to create, I want him (testUserX) to use the authenticate subkey for the login onto this server.
sec rsa1024/1CA56EBE6E0D128A
created: 2020-03-27 expires: never usage: C
trust: ultimate validity: ultimate
ssb rsa1024/7D9558836D7E9E72
created: 2020-03-27 expires: never usage: A
[ultimate] (1). admin <admin-test#example.com>
I tried to follow a few tutorials I found on the internet to do so but none of them worked so far. I have an Ubuntu 18.04 server and my gpg (GnuPG) version is 2.2.4.
Can anybody help me out how to do that? It must be rather simple but I wasn't able to do manage it. Thanks.
Edit: Maybe I should elaborate my answer what I have done so far.
On the Ubuntu server, I exported the public key of the authenticate subkey to ~/.ssh/authorized_keys
gpg --export-ssh-key 7D9558836D7E9E72! > 7D9558836D7E9E72.pub.ssh
cat ~/7D9558836D7E9E72.pub.ssh >> ~/.ssh/authorized_keys
Then I exported the private key to my Windows 10 computer and imported it there:
scp ferit#192.168.2.8:~/7D9558836D7E9E72.sub.key C:\Users\ferit\Downloads\
gpg --import 7D9558836D7E9E72.sub.key
So, question: How can I log in from Windows 10 to the Ubuntu server via PGP?
I am not sure the approach is right, but maybe I misunderstood something.
The idea is as follows:
each user on your system will be able to upload their public key on your server
when this is done, you can import the key to a keyring
then, when they want to login they first need to enter their user name
then, the server will fetch the matching key ID in the database
then, you generate a random challenge, that is PGP-encrypted using the public key of the user (and optionally yours), so that only the user (and optionally, you) is able to decipher the message
the user enters the response to the challenge
if the response matches the generated value, he/she will be logged in successfully.
To sum up, each user (even if there is just one at the moment...) should have their own key pair, and they provide it. You don't provide them with one, and you certainly don't share the same key with multiple users.
Everyone keeps their secret keys secret, but the public key may be (has to be) shared freely.
This is a type of 2FA, so I am sure you will easily find code samples for this task. But you didn't specify the language you will be using. Also, you are not exactly saying the purpose. 'Log in' is vague. Is the goal to log in to a website or some service like SSH ? Implementation will vary depending on the goal.

WinSCP authenticate to the server in automation mode, using the public key authentication

I am using WinSCP to automate the copy process to server and the authentication is only with username and password.
Script is:
open username:password#ipaddress:portno -hostkey=<hostkey>
Whereas now the authentication mode has to be changed to public key.
Script changed for authenticate through public key:
open username#ipaddress:portno -privatekey=mykey.ppk
Passphrase for the private key is requested after executing the above script, but is there any way that the passphrase of the private key can be provided in the same command?
Use the -passphrase switch of the open command.
See also WinSCP FAQ
How can I connect without entering private key passphrase each time?
Also, note, that you still should use the -hostkey switch.
open username:password#ipaddress:portno -hostkey=... -privatekey=... -passphrase=...

Public key ssh login from windows

My client provided me public key and asked me to do a ssh login. But i havent done any ssh login before. So can you please suggest me how to use public key for ssh login. I am using putty on windows
Here is a very nice tutorial on how to setup key based authentication usint putty on Windows.
http://www.ualberta.ca/CNS/RESEARCH/LinuxClusters/pka-putty.html
With SSH, public key is stored on the server and a user must have corresponding private key to log in. If this is your situation, you can specify your private key with PuTTY in one of two ways:
Configuration -> Connection -> SSH -> Auth -> Private key file for authentication
Use -i command-line option when starting PuTTY.
In both cases you need the private key in PuTTY format (.ppk). If your key is in a different format, you'll have to convert it using PuttyGen.

SSH Expect Password Issue with Login

Hi I've the following script that make an ssh login to my server.
spawn ssh presnetwork#192.168.244.14
expect "*(yes/no)?"
send "yes"
expect "password:"
send "pwd\n"
close
it works fine but it doesn't pass 'pwd' value to system, so script goes timeout and quit.
Any suggestions?
You could try with "KbdInteractiveAuthentication" set to "no"
(ssh -o KbdInteractiveAuthentication="no" presnetwork#192....). SSH by default uses Keyboard Interactive Authentication, which is something expect might not understand.
I would strongly recommend that you use public key authentication instead (as already recommended by Flo). It is way easier to handle, and way more secure, and way more comfortable. If you are just looking for a way to login to a remote server without having to enter the password everytime, take a look at ssh-agent, which will store the password for you after you entered it once in your desktop session. If you really don't want to enter your password, use pam_ssh, where your desktop login password will be used.
By default, the expect command is not yet installed. So, you to install it to acquire correct output.