Безопасный FTP с использованием аутентификации с помощью закрытого ключа в Java - PullRequest
0 голосов
/ 05 декабря 2011
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, но получаю ошибку аутентификации.

Я добавил открытый ключ в список авторизованных ключей на целевом сервере.И нет парольной фразы.

Есть ли что-то еще, что я должен сделать?Как, скажем, при генерации ключей?Есть ли шаг, который я пропускаю?

Есть ли другая библиотека, которую я могу использовать для реализации той же функции?

Ответы [ 2 ]

2 голосов
/ 05 декабря 2011

Убедитесь, что необходимые файлы существуют (id_rsa и id_rsa.pub на клиенте, author_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");
0 голосов
/ 05 декабря 2011

Вы скопировали ключ в файл $ HOME / .ssh / авторизованный_кредит на целевом сервере? Если это так, вы, вероятно, должны упомянуть об этом. Если нет, то это необходимо для того, чтобы это работало. Кроме того, вы генерируете ключ без пароля? Если закрытый ключ защищен паролем, вам нужно будет указать этот пароль для addIdentity.

После проверки этих вещей, я бы порекомендовал попробовать подключиться через командную строку, используя OpenSSH, так как код Java, который вы здесь видите, выглядит правильно. Если командная строка не работает, вызовите ее с -vvv, чтобы получить подробный вывод о том, что она делает. Возможно, сервер настроен с PubkeyAuthentication, установленным на №.

...