当前位置: 首页 > 知识库问答 >
问题:

使用JSch时的“无效私钥”

翟沈义
2023-03-14

我使用以下代码在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;
}

但仍然得到“无效私钥”异常。

共有3个答案

凤晨朗
2023-03-14

除了将OPENSSH密钥格式转换为原始JSch支持的格式之外,您还可以切换到JSch的分支,您可以在https://github.com/mwiede/jsch

您只需要将JSch Maven坐标替换为com.github.mwiede: jsch: 0.1.61

fork确实支持OPENSSH密钥格式和其他一些算法,这在将来可能会变得很重要,因为OPENSSH服务器将把允许的算法集限制为最安全的算法集。

潘星阑
2023-03-14

在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的较新用户才会发生异常,该密钥会输出此密钥头:

-----开始OPENSSH私钥------

而不是善良的RSA:

-----开始RSA私钥------

重新生成RSA密钥(ssh-keygen-t RSA)使异常消失。

编辑以下注释:如果您有OpenSSH 7.8及更高版本,则可能需要将-m PEM添加到生成命令中:ssh-keygen-t rsa-m PEM

颜君浩
2023-03-14

最新版本的OpenSSH(7.8及更新版本)默认情况下以新的OpenSSH格式生成密钥,该格式从以下开始:

-----BEGIN OPENSSH PRIVATE KEY-----

JSch不支持此密钥格式。

您可以使用ssh-keygen将密钥转换为经典的OpenSSH格式:

ssh-keygen -p -f file -m pem -P passphrase -N passphrase

(如果密钥未使用密码短语加密,请使用而不是密码短语

对于Windows用户:请注意,ssh-keygen.exe现在内置在Windows 10中。并且可以从Microsoft Win32-OpenSSH项目下载旧版本的Windows。

在Windows上,您也可以使用PuTTYgen(来自PuTTY包):

  • 启动PuTTYgen
  • 加载密钥
  • 转到转换

如果要使用ssh-keygen创建新密钥,只需添加-m PEM即可以经典格式生成新密钥:

ssh-keygen -m PEM
 类似资料:
  • 问题内容: 我正在使用以下代码在Java应用程序中使用Git。我有一个有效的密钥(一直使用),并且之前使用相同的密钥和git存储库,此特定代码对我有用,但是现在出现以下异常: 无效的私钥:[B @ 59c40796。 在这一行: 我的完整代码: 在线搜索后,我将createDefaultJSch更改为使用pemWriter: 但是仍然会收到 “无效的私钥” 异常。 问题答案: 我也偶然发现了这个问

  • 问题内容: 我正在使用netbeans 7.2运行JDK 1.7和Windows 7,我已经使用putty- keygen生成了SSH私钥和公钥对(SSH2-2048位)。我没有私钥密码。我现在正在尝试使用SFTP连接到主机之一。但是,当我通过私钥(ppk)设置身份时,代码将返回无效的私钥错误。我在WinSCP中使用了相同的私钥来连接到相同的主机,并且工作正常。请帮助我解决错误。这是我的代码: 问

  • 我使用NetBeans7.2运行JDK1.7和Windows7,我使用putty-keygen生成了一个SSH私钥和公钥对(SSH2-2048位)。我没有任何私钥密码。我现在正尝试使用SFTP连接到其中一台主机。但是当我传递私钥(ppk)来设置身份时,代码返回无效私钥错误。我在WinSCP中使用了相同的私钥来连接到相同的主机&它工作得很好。请帮助我解决这个错误。下面是我的代码:

  • 我正在使用以下代码在Java应用程序中使用Git。我有一个有效的密钥(一直使用它),并且这个特定的代码以前用相同的密钥和git存储库为我工作过,但是现在我得到了以下异常: PrivateKey无效:[B@59C40796. 在这一行: 在网上搜索后,我将createDefaultJSch更改为使用PEMWriter: 但仍然得到“无效的PrivateKey”异常。

  • 我们正在尝试使用JSCH从远程服务器下载文件。尝试时,两台服务器之间已经建立了SFTP密钥交换 它在不要求任何密码的情况下成功连接。但在java代码中,当我们尝试使用JSCH连接时,会出现无效私钥异常。 我所做的代码如下所示 编辑: im使用的JSCH版本是0.1.54 私钥的开头就像 我甚至尝试将私钥转换为openssh格式,但遇到了一些异常 如果我从命令中删除-f,它会工作,但我相信该文件没有

  • JSch日志: 的日志: