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.
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.
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.
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):
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With