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.
I also stumbled upon this issue. running Jgit on mac, for some users we saw the following exception:
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
You read a file named
.pem
and de-base64 all of it and treat the result as PKCS8-unencrypted, apparently successfully. This means the file was NOT PEM-format. PEM format at minimum MUST have the dash-BEGIN and dash-END lines to be valid, which if not removed cause de-base64 to either fail or be wrong. (Some PEM formats also have 822-style headers which must be handled.)You appear to be using BouncyCastle, but in my versions there is no
PKCS8Generator
constructor that takes onlyRSAPrivateKey
. The closest thing that works isJcaPKCS8Generator (RSAPrivateKey implements PrivateKey, OutputEncryptor=null)
(i.e. a different but related class, and two arguments not one).PemWriter
is buffered, and you didn't flush it before looking at the underlyingStringWriter
. As a resultwriter.toString().getBytes()
is an empty/zero-length array, whichJSch
rightly considers invalid.With #2 and #3 fixed and using my input, and calling
JSch
directly instead of viaJGit
, it works for me.JSch does not support this key format. It supports only RSAPrivateKey. This command works for me. Try this solution
Recent versions of OpenSSH (7.8 and newer) generate keys in new OpenSSH format by default, which start with:
JSch does not support this key format.
You can use
ssh-keygen
to convert the key to the classic OpenSSH format:(if the key is not encrypted with a passphrase, use
""
instead ofpassphrase
)If you are on Windows, you can use PuTTYgen (from PuTTY package):
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: