java中使用私钥身份验证的安全FTP

java中使用私钥身份验证的安全FTP,java,solaris,rsa,sftp,private-key,Java,Solaris,Rsa,Sftp,Private Key,正如您从我注释的代码中看到的,我已经尽了一切可能让它工作,唯一有效的方法是直接设置密码。我正在尝试使用生成的RSA私钥,但我不断得到一个身份验证失败 我已将公钥添加到目标服务器上的授权密钥列表中。而且没有密码短语 我还有别的事要做吗?比如说,在生成密钥时?有没有我错过的一步 是否有其他库可用于实现相同的功能?您是否已将密钥复制到目标服务器上的文件$HOME/.ssh/authorized_keys中?如果是这样的话,你可能应该提到这一点。如果没有,这是工作所必需的。另外,您是否正在生成没有密码的

正如您从我注释的代码中看到的,我已经尽了一切可能让它工作,唯一有效的方法是直接设置密码。我正在尝试使用生成的RSA私钥,但我不断得到一个身份验证失败

我已将公钥添加到目标服务器上的授权密钥列表中。而且没有密码短语

我还有别的事要做吗?比如说,在生成密钥时?有没有我错过的一步


是否有其他库可用于实现相同的功能?

您是否已将密钥复制到目标服务器上的文件$HOME/.ssh/authorized_keys中?如果是这样的话,你可能应该提到这一点。如果没有,这是工作所必需的。另外,您是否正在生成没有密码的密钥?如果私钥受密码保护,则需要将该密码提供给
addIdentity


在验证这些内容之后,我建议尝试使用OpenSSH通过命令行进行连接,因为这里的Java代码看起来是正确的。如果命令行不起作用,请使用-vvv调用它,以获取有关它正在执行的操作的详细输出。服务器可能配置了
PubkeyAuthentication
设置为no.

确保必要的文件存在(客户端上的id\u rsa和id\u rsa.pub,服务器上的授权密钥)。确保您可以使用这些文件与其他工具(如
ssh
)一起使用公钥身份验证

如果这看起来没问题,那么问题可能出在Java安全提供商身上。如果你认为你有合适的文件,请继续阅读

RSA私钥存储有不同的格式,SSH使用的格式不是标准格式。大多数提供者都希望有一种称为CRT-RSA密钥的东西,当JSch没有给他们这种格式的密钥时,他们会引发一个异常,JSch会默默地接受这个异常,并继续使用下一个身份验证方法

你的供应商是什么?以下代码片段将帮助您找到答案:

import com.jcraft.jsch.*;
import com.jcraft.jsch.JSchException;
import oracle.jdbc.driver.OracleDriver;
import java.io.*;
import java.util.*;
import java.sql.*;
import java.net.*;

public class SecureFTP {

public static void main(String[] args) throws IOException , ClassNotFoundException, JSchException, SftpException{



    JSch jsch = new JSch();
    File file = new File("/home/xxxxx/.ssh/id_rsa");
    Session session = null;
    URL keyFileURL = null;
    URI keyFileURI = null;
    if (file.exists())
    {
        keyFileURL = file.toURL();
        if (keyFileURL == null)
        {
            System.out.println("what");
            throw new RuntimeException("Key file not found in classpath");
        }
    }
    else System.out.println("FIle not found");
    try{
             keyFileURI = keyFileURL.toURI();
    }
    catch(Exception URISyntaxException)
    {
        System.out.println("Wrong URL");
}


    String privateKey = ".ssh/id_rsa";

    //jsch.addIdentity(privateKey);

    jsch.addIdentity(new File(keyFileURI).getAbsolutePath());
    System.out.println(new File(keyFileURI).getAbsolutePath() + " LOL");
    session = jsch.getSession("username", "servername");
    //session.setPassword("password");

    java.util.Properties config = new java.util.Properties();
    config.put("StrictHostKeyChecking", "no");
    session.setConfig(config);

    // connect
    session.connect();

    // get SFTP channel
    Channel channel = session.openChannel("sftp");
    channel.connect();
    ChannelSftp schannel = (ChannelSftp) channel;

    FileInputStream fis = new FileInputStream(sourcefile);
    schannel.put(fis, destinationfile );
    fis.close();



}

    schannel.exit();
    session.disconnect();

}

}

更新:我做了一些检查,从Java5开始,SunPKCS11提供程序以最高优先级安装在Solaris系统上,以提高性能。因为我不运行Solaris,所以无法测试它,但我相信这可能是导致问题的原因

JSch不允许您通过其API指定用于此操作的提供程序,因此您必须更改已安装提供程序的优先级。事实上,我建议尝试从这个应用程序中删除SunPKCS11;在应用程序启动时运行此代码一次:

import java.security.KeyFactory;
…

KeyFactory f = KeyFactory.getInstance("RSA");
System.out.println(f.getProvider().getName());

您可以查看syslog文件中的服务器以了解身份验证失败的原因吗?如果这是一个Linux服务器,那么/var/log/messages可能会失败?询问您的系统管理员或本地IT。使用该信息更新问题,我将公钥复制到授权密钥。i、 e./.ssh/id_rsa.pub到另一台服务器上的授权_密钥提供程序是SunPKCS11 Solaris。我确保这些密钥存在,并且能够使用这些密钥进行sftp和ssh(即没有密码/密码短语)。但是,对于jsch,它给了我这个例外。我如何确保格式符合要求?@roymustang86好吧,这很奇怪。默认情况下,Oracle JVM应该使用SunRsaSign提供程序来创建RSA密钥,它可以处理这种情况。PKCS11提供程序是可插拔的,因此它可以是任何东西,但通常您会将其与存储在硬件中的密钥(如智能卡)一起使用。如果您的系统上有智能卡读卡器或硬件加密模块,则PKCS11提供程序可能已被配置为首选,这可能确实会导致问题。如下所示列出您的提供程序:
for(Provider p:Security.getProviders())System.out.println(p.getName())列表按以下顺序排列:SunPKCS11 Solaris SUNRASSIGN SUNRASSIGN SunJSSE SunJCE SunJGSS SunSASLthanks很多时候,我都不知道如何解决这个问题。是的,我对JSch在错误处理、错误报告和提供程序配置方面的质量印象不深。
Security.removeProvider("SunPKCS11-Solaris");