在java中使用私钥身份验证保护FTP [英] Secure FTP using private key authentication in java

查看:292
本文介绍了在java中使用私钥身份验证保护FTP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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 私钥,但我一直遇到身份验证失败.

As you can see from the code I have commented out, I have tried everything possible to get this working and the only thing that works is if I set the password directly. I am trying to use the RSA private key generated, but I keep getting an auth fail.

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

I have added the public key to the list of authorized keys on the target server. And there is no passphrase.

还有什么我应该做的吗?比如说,在生成密钥时?有没有我遗漏的步骤?

Is there something else I am supposed to do? Like say, while generating the keys? Is there a step I am missing?

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

Is there another library I can use to implement the same function?

推荐答案

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

Make sure the necessary files exist (id_rsa and id_rsa.pub on the client, authorized_keys on the server). Make sure you can use public key authentication with another tool, like ssh, using these files.

如果看起来没问题,那么问题可能出在您的 Java 安全提供程序上.如果您认为您拥有正确的文件,请继续阅读.

If that looks alright, the problem may be with your Java security provider. Read on if you think you have the right files in place.

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

There are different formats for RSA private key storage, and SSH uses one that is not standard. Most providers expect something called a CRT RSA key, and when JSch doesn't give them a key in that format, they raise an exception which JSch silently eats and goes on to the next authentication method.

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

What is your provider? The following snippet will help you find out:

import java.security.KeyFactory;
…

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

<小时>

更新:我进行了一些检查,从 Java 5 开始,SunPKCS11 提供程序在 Solaris 系统上以最高优先级安装,以提高性能.由于我不运行 Solaris,因此无法对其进行测试,但我相信这可能是导致问题的原因.


Update: I did some checking around, and as of Java 5, the SunPKCS11 provider is installed with the highest precedence on Solaris systems, for performance. Since I don't run Solaris, I can't test it, but I believe this may be causing the problem.

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

JSch doesn't allow you to specify the provider to use for this operation through its API, so you will have to change the precedence of the installed providers. In fact, I'd suggest trying to remove the SunPKCS11 from this application; run this code once when your application starts up:

Security.removeProvider("SunPKCS11-Solaris");

这篇关于在java中使用私钥身份验证保护FTP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆