从JSch迁移至Apache Mina:为JGit配置私钥认证SSH会话工厂
迁移JGit SSH认证至Apache Mina以支持RSA-SHA2-512算法
Azure仓库已终止SSH-RSA算法支持,需升级使用RSA-SHA2-512,但JSch库不支持该算法,因此需要将基于JSch的JGit SSH私钥认证逻辑迁移至Apache Mina SSHD。
原JSch实现代码
File privateKey = new File("/path/to/local/privateKeyFile"); Repository repository = new FileRepositoryBuilder() .setMustExist(true) .setGitDir(new File("/path/to/local/repo/.git")) .build(); Git git = new Git(repository); PullCommand pullCmd = git.pull() .setTransportConfigCallback(transport -> { SshTransport sshTransport = (SshTransport) transport; sshTransport.setSshSessionFactory( new JschConfigSessionFactory() { @Override protected void configure(OpenSshConfig.Host host, Session session) { session.setConfig("StrictHostKeyChecking", "no"); } @Override protected JSch createDefaultJSch(FS fs) throws JSchException { JSch defaultJSch = new JSch(); defaultJSch.addIdentity(privateKey.getAbsolutePath()); return defaultJSch; } } ); });
问题分析(用户提交的Mina代码)
用户的代码存在两个关键问题:
- 过早调用
client.stop(),SSH客户端在拉取操作执行前就被关闭,导致无法建立连接 - 缺少对主机密钥检查的配置,未对齐原JSch的安全策略
正确的Apache Mina配置实现
依赖说明
确保项目中引入以下依赖(以Maven为例):
<dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit</artifactId> <version>6.7.0.202309050840-r</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.ssh.apache</artifactId> <version>6.7.0.202309050840-r</version> </dependency>
完整代码实现
import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.PullCommand; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.storage.file.FileRepositoryBuilder; import org.eclipse.jgit.transport.SshTransport; import org.eclipse.jgit.transport.ssh.apache.GitSshdSessionFactory; import org.eclipse.jgit.transport.ssh.apache.SshdSessionFactoryBuilder; import org.eclipse.jgit.util.FS; import org.apache.sshd.client.SshClient; import org.apache.sshd.client.keyverifier.AcceptAllServerKeyVerifier; import org.apache.sshd.common.keyprovider.FileKeyPairProvider; import java.io.File; import java.io.IOException; public class MinaSshGitPull { public static void main(String[] args) throws IOException, GitAPIException { File privateKey = new File("/path/to/local/privateKeyFile"); Repository repository = new FileRepositoryBuilder() .setMustExist(true) .setGitDir(new File("/path/to/local/repo/.git")) .build(); Git git = new Git(repository); SshClient client = null; try { // 初始化并配置SshClient client = SshClient.setUpDefaultClient(); // 禁用主机密钥检查(与原JSch配置一致) client.setServerKeyVerifier(AcceptAllServerKeyVerifier.INSTANCE); // 设置私钥提供者,Apache Mina默认支持RSA-SHA2-512 client.setKeyIdentityProvider(new FileKeyPairProvider(privateKey.toPath())); client.start(); // 配置JGit的SSH传输会话工厂 PullCommand pullCmd = git.pull() .setTransportConfigCallback(transport -> { SshTransport sshTransport = (SshTransport) transport; sshTransport.setSshSessionFactory(new GitSshdSessionFactory( new SshdSessionFactoryBuilder() .setSshClient(client) .setFS(FS.DETECTED) .build() )); }); // 执行拉取操作 pullCmd.call(); System.out.println("拉取完成"); } finally { // 确保资源正确释放 if (client != null && client.isStarted()) { client.stop(); } git.close(); repository.close(); } } }
关键配置说明
- 主机密钥检查:通过
AcceptAllServerKeyVerifier禁用严格检查,与原JSch代码的StrictHostKeyChecking=no行为完全一致 - 算法支持:Apache Mina SSHD默认支持RSA-SHA2-512,无需额外配置即可适配Azure仓库的要求
- 生命周期管理:将
client.stop()放在finally块中,确保拉取操作完成后再关闭客户端,避免连接提前中断 - 会话工厂构建:使用
SshdSessionFactoryBuilder关联SshClient与JGit的文件系统,保证配置参数正确传递
内容的提问来源于stack exchange,提问作者Izaya
相关产品推荐
相关产品推荐

