"Invalid privatekey" when using JSch

I also stumbled upon this issue. running Jgit on mac, for some users we saw the following exception:

org.eclipse.jgit.transport.JschConfigSessionFactory.getSession(JschConfigSessionFactory.java:160)
    at org.eclipse.jgit.transport.SshTransport.getSession(SshTransport.java:137)
    at org.eclipse.jgit.transport.TransportGitSsh$SshFetchConnection.<init>(TransportGitSsh.java:274)
    at org.eclipse.jgit.transport.TransportGitSsh.openFetch(TransportGitSsh.java:169)
    at org.eclipse.jgit.transport.FetchProcess.executeImp(FetchProcess.java:136)
    at org.eclipse.jgit.transport.FetchProcess.execute(FetchProcess.java:122)
    at org.eclipse.jgit.transport.Transport.fetch(Transport.java:1236)
    at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:234)
    ... 17 more
Caused by: com.jcraft.jsch.JSchException: invalid privatekey: [B@e4487af
    at com.jcraft.jsch.KeyPair.load(KeyPair.java:664)
    at com.jcraft.jsch.KeyPair.load(KeyPair.java:561)
    at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:40)
    at com.jcraft.jsch.JSch.addIdentity(JSch.java:407)
    at com.jcraft.jsch.JSch.addIdentity(JSch.java:367)
    at org.eclipse.jgit.transport.JschConfigSessionFactory.getJSch(JschConfigSessionFactory.java:276)
    at org.eclipse.jgit.transport.JschConfigSessionFactory.createSession(JschConfigSessionFactory.java:220)
    at org.eclipse.jgit.transport.JschConfigSessionFactory.createSession(JschConfigSessionFactory.java:176)
    at org.eclipse.jgit.transport.JschConfigSessionFactory.getSession(JschConfigSessionFactory.java:110)

The root cause was discovered to be the ssh private key mismatch. The exception only happened for users with key of newer kind ed25519, which outputs this key header:

-----BEGIN OPENSSH PRIVATE KEY-----

instead of kind RSA:

-----BEGIN RSA PRIVATE KEY-----

regenerating an RSA key (ssh-keygen -t rsa), made the exception go away.

Edit following comments: If you have OpenSSH 7.8 and above you might need to add -m PEM to the generation command: ssh-keygen -t rsa -m PEM


Recent versions of OpenSSH (7.8 and newer) generate keys in new OpenSSH format by default, which starts with:

-----BEGIN OPENSSH PRIVATE KEY-----

JSch does not support this key format.


You can use ssh-keygen to convert the key to the classic OpenSSH format:

ssh-keygen -p -f <privateKeyFile> -m pem -P passphrase -N passphrase

This "abuses" -p (change passphrase) command. It will overwrite the private key file identified by the -f option with a new private key in the classic OpenSSH format (pem). You can keep the current passphrase as the new passphrase. If the key was not encrypted with a passphrase, use "" instead of passphrase. After, you can use ssh-keygen -y -e -f <privateKeyFile> >temp.pub to compare public keys and verify the existing public key works with the new format of private key.

For Windows users: Note that ssh-keygen.exe is now built-in in Windows 10/11. And can be downloaded from Microsoft Win32-OpenSSH project for older versions of Windows.


On Windows, you can also use PuTTYgen (from PuTTY package):

  • Start PuTTYgen
  • Load the key
  • Go to Conversions > Export OpenSSH key.
    For RSA keys, it will use the classic format.

If you are creating a new key with ssh-keygen, just add -m PEM to generate the new key in the classic format:

ssh-keygen -m PEM

Tags:

Java

Ssh

Jsch