使用JGit键可以安全地访问Git存储库

我正在使用JGit访问远程Git仓库,我需要使用SSH 。 JGit使用JSch提供安全访问。 但是,我不确定如何为JGit设置密钥文件和知道的hosts文件。 我试过的如下。

使用子类化JSchConfigSessionFactory创建SshSessionFactory的自定义配置:

public class CustomJschConfigSessionFactory extends JschConfigSessionFactory { @Override protected void configure(OpenSshConfig.Host host, Session session) { session.setConfig("StrictHostKeyChecking", "yes"); } } 

在我访问远程Git仓库的类中,执行以下操作:

 CustomJschConfigSessionFactory jschConfigSessionFactory = new CustomJschConfigSessionFactory(); JSch jsch = new JSch(); try { jsch.addIdentity(".ssh/id_rsa"); jsch.setKnownHosts(".ssh/known_hosts"); } catch (JSchException e) { e.printStackTrace(); } SshSessionFactory.setInstance(jschConfigSessionFactory); 

我无法弄清楚如何将此JSch对象与JGit关联,以便它可以成功连接到远程存储库。 当我尝试使用JGit克隆它时,我得到以下exception:

 org.eclipse.jgit.api.errors.TransportException: git@git.test.com:abc.org/test_repo.git: reject HostKey: git.test.com at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:137) at org.eclipse.jgit.api.CloneCommand.fetch(CloneCommand.java:178) at org.eclipse.jgit.api.CloneCommand.call(CloneCommand.java:125) at GitTest.cloneRepo(GitTest.java:109) at GitTest.main(GitTest.java:223) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) Caused by: org.eclipse.jgit.errors.TransportException: git@git.test.com:abc.org/test_repo.git: reject HostKey: git.test.com at org.eclipse.jgit.transport.JschConfigSessionFactory.getSession(JschConfigSessionFactory.java:142) at org.eclipse.jgit.transport.SshTransport.getSession(SshTransport.java:121) at org.eclipse.jgit.transport.TransportGitSsh$SshFetchConnection.(TransportGitSsh.java:248) at org.eclipse.jgit.transport.TransportGitSsh.openFetch(TransportGitSsh.java:147) 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:1104) at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:128) ... 9 more Caused by: com.jcraft.jsch.JSchException: reject HostKey: git.test.com at com.jcraft.jsch.Session.checkHost(Session.java:748) at com.jcraft.jsch.Session.connect(Session.java:321) at org.eclipse.jgit.transport.JschConfigSessionFactory.getSession(JschConfigSessionFactory.java:116) ... 16 more 

我已将git.test.com条目添加到我的/etc/hosts文件中。 我使用相同的代码来访问带有http url的git repo,因此代码运行正常。 这是失败的关键处理部分。 有关如何处理这个的任何想法?

您需要覆盖自定义工厂类中的getJSch方法:

 class CustomConfigSessionFactory extends JschConfigSessionFactory { @Override protected JSch getJSch(final OpenSshConfig.Host hc, FS fs) throws JSchException { JSch jsch = super.getJSch(hc, fs); jsch.removeAllIdentity(); jsch.addIdentity( "/path/to/private/key" ); return jsch; } } 

调用jsch.removeAllIdentity非常重要; 没有它它似乎没有用。

警告:我在Scala中编写了上述内容,然后将其翻译为Java,因此可能不太正确。 原始的Scala如下:

 class CustomConfigSessionFactory extends JschConfigSessionFactory { override protected def getJSch( hc : OpenSshConfig.Host, fs : FS ) : JSch = { val jsch = super.getJSch(hc, fs) jsch.removeAllIdentity() jsch.addIdentity( "/path/to/private/key" ) jsch } } 

Jsch sesems不喜欢散列格式的known_hosts文件 – 它必须符合以下格式:

ssh-keyscan -t rsa hostname >> ~/.ssh/known_hosts

例如

  ssh-rsa  

不:

  |1|= ecdsa-sha2-nistp256 = 

管理找到问题。 服务器端的公钥具有与通常的id_rsa.pub不同的名称,而我身边的私钥是id_rsa。 JSch默认情况下公钥的名称与私钥和.pub后缀相同。 使用具有通用名称的密钥对(例如:private = key_1和public = key_1.pub)解决了该问题。