"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