使用java中的私钥身份验证来保护FTP

时间:2011-12-05 17:13:19

标签: java solaris rsa sftp private-key

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();

}

}

正如您从我已经注释掉的代码中看到的那样,我已经尝试了所有可能的工作,唯一可行的是我直接设置密码。我正在尝试使用生成的RSA私钥,但我一直在使用auth失败。

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

我还应该做些什么吗?就像说,在生成密钥的同时?我缺少一步吗?

我可以使用另一个库来实现相同的功能吗?

2 个答案:

答案 0 :(得分:2)

确保存在必要的文件(客户端上的id_rsa和id_rsa.pub,服务器上的authorized_keys)。确保您可以使用其他工具(例如ssh)使用这些文件进行公钥身份验证。

如果看起来不错,问题可能在于您的Java安全提供程序。如果您认为自己拥有正确的文件,请继续阅读。

RSA私钥存储有不同的格式,SSH使用非标准格式。大多数提供商都期望一种称为CRT RSA密钥的东西,当JSch没有给他们提供该格式的密钥时,他们会引发一个例外,JSch默默地吃掉并继续下一个身份验证方法。

您的提供者是什么?以下代码段将帮助您了解:

import java.security.KeyFactory;
…

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

更新:我做了一些检查,从Java 5开始,SunPKCS11提供程序安装时在Solaris系统上具有最高优先级,以提高性能。由于我没有运行Solaris,我无法测试它,但我相信这可能会导致问题。

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

Security.removeProvider("SunPKCS11-Solaris");

答案 1 :(得分:0)

您是否已将密钥复制到目标服务器上的$ HOME / .ssh / authorized_keys文件中?如果是这样,你应该提一下。如果没有,那就需要这个。另外,你是否在没有密码的情况下生成密钥?如果私钥受密码保护,则需要将该密码提供给addIdentity

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