我正在使用以下代码在Java应用程序中使用Git。我有一个有效的密钥(一直使用),并且之前使用相同的密钥和git存储库,此特定代码对我有用,但是现在出现以下异常:
无效的私钥:[B @ 59c40796。
在这一行:
jSch.addIdentity("<key_path>/private_key.pem");
我的完整代码:
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; } };
在线搜索后,我将createDefaultJSch更改为使用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; }
但是仍然会收到 “无效的私钥” 异常。
我也偶然发现了这个问题。在 mac* 上运行 Jgit ,对于某些用户,我们看到了以下异常: *
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)
发现根本原因是ssh私钥不匹配。仅对于使用较新类型 ed25519的 密钥的用户才发生此异常,该用户输出以下密钥头:
-----BEGIN OPENSSH PRIVATE KEY-----
而不是 RSA :
-----BEGIN RSA PRIVATE KEY-----
重新生成RSA密钥(ssh-keygen -t rsa),该异常消失了。
ssh-keygen -t rsa
编辑以下注释:如果您具有OpenSSH 7.8及更高版本,则可能需要在生成命令中添加-m PEM: ssh-keygen -t rsa -m PEM
ssh-keygen -t rsa -m PEM