Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Invalid privatekey" when using JSch

Tags:

java

ssh

jsch

I'm using the following code to work with Git in a Java application. I have a valid key (use it all the time), and this specific code has work for me before with the same key and git repository, but now I get the following exception:

invalid privatekey: [B@59c40796.

At this line:

jSch.addIdentity("<key_path>/private_key.pem"); 

My full code:

    String remoteURL = "ssh://git@<git_repository>";     TransportConfigCallback transportConfigCallback = new SshTransportConfigCallback();     File gitFolder = new File(workingDirectory);     if (gitFolder.exists()) FileUtils.delete(gitFolder, FileUtils.RECURSIVE);      Git git = Git.cloneRepository()             .setURI(remoteURL)             .setTransportConfigCallback(transportConfigCallback)             .setDirectory(new File(workingDirectory))             .call(); }   private static class SshTransportConfigCallback implements TransportConfigCallback {     private final SshSessionFactory sshSessionFactory = new JschConfigSessionFactory() {         @Override         protected void configure(OpenSshConfig.Host hc, Session session) {             session.setConfig("StrictHostKeyChecking", "no");         }          @Override         protected JSch createDefaultJSch(FS fs) throws JSchException {             JSch jSch = super.createDefaultJSch(fs);             jSch.addIdentity("<key_path>/private_key.pem");              return jSch;         }     }; 

After searching online, I've change createDefaultJSch to use pemWriter:

@Override protected JSch createDefaultJSch(FS fs) throws JSchException {     JSch jSch = super.createDefaultJSch(fs);     byte[] privateKeyPEM = null;      try {         KeyFactory keyFactory = KeyFactory.getInstance("RSA");          List<String> lines = Files.readAllLines(Paths.get("<my_key>.pem"), StandardCharsets.US_ASCII);         PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(String.join("", lines)));         RSAPrivateKey privKey = (RSAPrivateKey) keyFactory.generatePrivate(privSpec);          PKCS8Generator pkcs8 = new PKCS8Generator(privKey);          StringWriter writer = new StringWriter();         PemWriter pemWriter = new PemWriter(writer);         pemWriter.writeObject(pkcs8);          privateKeyPEM = writer.toString().getBytes("US-ASCII");      } catch (Exception e) {         e.printStackTrace();     }      jSch.addIdentity("git", privateKeyPEM, null, null);      return jSch; } 

But still getting "invalid privatekey" exception.

like image 920
o_b7 Avatar asked Nov 03 '18 18:11

o_b7


People also ask

What is JSch addIdentity?

addIdentity(String prvkey, String pubkey, byte[] passphrase) Adds an identity to be used for public-key authentication. protected void. addSession(Session session) Adds a session to our session pool.

Can we use JSch for SSH key based communication?

It is possible. Have a look at JSch. addIdentity(...) This allows you to use key either as byte array or to read it from file.


2 Answers

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 file -m pem -P passphrase -N passphrase 

(if the key is not encrypted with a passphrase, use "" instead of passphrase)

For Windows users: Note that ssh-keygen.exe is now built-in in Windows 10. 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 
like image 72
Martin Prikryl Avatar answered Oct 18 '22 10:10

Martin Prikryl


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

like image 39
Natan Avatar answered Oct 18 '22 08:10

Natan