Подтвердить что ты не робот

"Ошибка аутентификации" в jsch-0.1.42 с Java 1.4.2

У меня есть эта простая Java-программа, которая использует Jsch для подключения к SFTP-серверу.

Соединение с ошибкой "Auth fail" в Java 1.4.2, но оно отлично соединяется с Java 1.7.

try {
    JSch jsch = new JSch();

    jsch.setKnownHosts(KNOWN_HOSTS_PATH);
    jsch.addIdentity(PRIVATE_KEY_PATH, PASSPHRASE);

    Session session = jsch.getSession(USERNAME, HOSTNAME, 22);
    session.connect(2500);

    Channel channel = session.openChannel("shell");
    channel.setInputStream(System. in );
    channel.setOutputStream(System.out);
    channel.connect();
} catch (Exception e) {
    e.printStackTrace(System.err);
}

Ключ, который я использую, - это бит ключа ssh-rsa 4096. Файл ключа .pub существует в том же каталоге, что и закрытый ключ.

При подключении регистратора я вижу следующие сообщения перед исключением (которое встречается на channel.connect();):

INFO: Connecting to <redacted> port 22
INFO: Connection established
INFO: Remote version string: SSH-2.0-OpenSSH_5.1p1 Debian-5
INFO: Local version string: SSH-2.0-JSCH-0.1.42
INFO: CheckCiphers: aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-ctr,arcfour,arcfour128,arcfour256
INFO: arcfour is not available.
INFO: arcfour128 is not available.
INFO: arcfour256 is not available.
INFO: SSH_MSG_KEXINIT sent
INFO: SSH_MSG_KEXINIT received
INFO: kex: server->client aes128-ctr hmac-md5 none
INFO: kex: client->server aes128-ctr hmac-md5 none
INFO: SSH_MSG_KEXDH_INIT sent
INFO: expecting SSH_MSG_KEXDH_REPLY
INFO: ssh_rsa_verify: signature true
INFO: Host '<redacted>' is known and mathces the RSA host key
INFO: SSH_MSG_NEWKEYS sent
INFO: SSH_MSG_NEWKEYS received
INFO: SSH_MSG_SERVICE_REQUEST sent
INFO: SSH_MSG_SERVICE_ACCEPT received
INFO: Authentications that can continue: publickey,keyboard-interactive,password
INFO: Next authentication method: publickey
INFO: Authentications that can continue: password
INFO: Next authentication method: password
INFO: Disconnecting from <redacted> port 22
com.jcraft.jsch.JSchException: Auth fail
        at com.jcraft.jsch.Session.connect(Session.java:452)
        at TestJsch.main(TestJsch.java:19)

Когда я запускаю ту же программу с Java 1.7, она говорит

INFO: Connecting to <redacted> port 22
INFO: Connection established
INFO: Remote version string: SSH-2.0-OpenSSH_5.1p1 Debian-5
INFO: Local version string: SSH-2.0-JSCH-0.1.42
INFO: CheckCiphers: aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-ctr,arcfour,arcfour128,arcfour256
INFO: SSH_MSG_KEXINIT sent
INFO: SSH_MSG_KEXINIT received
INFO: kex: server->client aes128-ctr hmac-md5 none
INFO: kex: client->server aes128-ctr hmac-md5 none
INFO: SSH_MSG_KEXDH_INIT sent
INFO: expecting SSH_MSG_KEXDH_REPLY
INFO: ssh_rsa_verify: signature true
INFO: Host '<redacted>' is known and mathces the RSA host key
INFO: SSH_MSG_NEWKEYS sent
INFO: SSH_MSG_NEWKEYS received
INFO: SSH_MSG_SERVICE_REQUEST sent
INFO: SSH_MSG_SERVICE_ACCEPT receivedINFO: Authentications that can continue: publickey,keyboard-interactive,password
INFO: Next authentication method: publickey
INFO: Authentication succeeded (publickey).
Linux <redacted> 2.6.26-2-amd64 #1 SMP Mon Jun 13 16:29:33 UTC 2011 x86_64

<server welcome message follows>

Я установил Java Cryptography Extensions (JCE) для 1.4 VM.

Что может быть источником этой проблемы?

4b9b3361

Ответ 1

У Java есть ограничение на использование сильного алгоритма криптографии. Проверьте содержимое $JRE_HOME/lib/security/US_Export_policy.jar и $JRE_HOME/lib/security/local_policy.jar. Если вы найдете что-то вроде этого:

// File: default_local.policy
// Some countries have import limits on crypto strength.
// This policy file is worldwide importable.
grant {
    permission javax.crypto.CryptoPermission "DES", 64;
    permission javax.crypto.CryptoPermission "DESede", *;
    permission javax.crypto.CryptoPermission "RC2", 128,
                   "javax.crypto.spec.RC2ParameterSpec", 128;
    permission javax.crypto.CryptoPermission "RC4", 128;
    permission javax.crypto.CryptoPermission "RC5", 128,
          "javax.crypto.spec.RC5ParameterSpec", *, 12, *;
    permission javax.crypto.CryptoPermission "RSA", 2048;
    permission javax.crypto.CryptoPermission *, 128;
};

Решение состоит в том, чтобы загрузить и установить JCE Unlimited Strength Jurisdiction Policy. Раньше он находился на сайте Sun, теперь я не знаю, где его можно найти.

Вы можете прочитать в этой статье

EDIT: После некоторых исследований я обнаружил, что мой ответ неверен.

Java 1.4 не поддерживает ключи RSA длиной более 2048 байтов BUG 4524097

Ответ 2

Мои проблемы с jsch связаны с разрешениями. Поэтому я бы сделал следующее, чтобы устранить их как проблемы.

  • Убедитесь, что вы можете отправить ssh на удаленный компьютер в командной строке, используя сгенерированные ключи.
  • Передайте пароль и убедитесь, что вы можете подключиться к удаленному компьютеру.
  • Проверьте права на локальный каталог и удаленное хорошее резюме ssh.
  • Попробуйте использовать локальный хост как удаленный.

Не удалось загрузить исходный код и выполнить шаг, хотя он находится в сеансе отладки.

Ответ 3

Вы пытались использовать Open SSH-ключ? jsch использует открытые форматы ключей SSH. Вы можете преобразовать свой существующий в формат Open SSH. Вот как это сделать: используйте keygen keygen и загрузите существующий ключ. Вам может быть предложено ввести пароль, чтобы расшифровать его. После этого нажмите на вариант конверсий выше и выберите "Экспорт ключа OpenSSH". Используйте этот вновь созданный ключ в вашей программе выше. Надеюсь, это поможет.

Ответ 4

Этот код отлично работает...

public class Exec2 {

static String SSH_SERVER_PATH = "localhost";
static String SSH_SERVER_USERNAME = "root";
static String SSH_SERVER_PASSWORD = "root";

public static void main(String[] arg) {
    try {
        JSch jsch = new JSch();
        String host = SSH_SERVER_PATH;
        String user = SSH_SERVER_USERNAME;

        Session session = jsch.getSession(user, host, 22);

        // username and password will be given via UserInfo interface.

        UserInfo ui = new MyUserInfo();
        session.setUserInfo(ui);
        session.connect();

        String command = "uname";

        Channel channel = session.openChannel("exec");
        ((ChannelExec) channel).setCommand(command);

        channel.setInputStream(null);

        ((ChannelExec) channel).setErrStream(System.err);

        InputStream in = channel.getInputStream();

        channel.connect();

        byte[] tmp = new byte[1024];
        while (true) {
            while (in.available() > 0) {
                int i = in.read(tmp, 0, 1024);
                if (i < 0)
                    break;
                System.out.print(new String(tmp, 0, i));
            }
            if (channel.isClosed()) {
                System.out.println("exit-status: " + channel.getExitStatus());
                break;
            }
            try {
                Thread.sleep(1000);
            } catch (Exception ee) {
            }
        }
        channel.disconnect();
        session.disconnect();
    } catch (Exception e) {
        System.out.println(e);
    }
}

public static class MyUserInfo implements UserInfo, UIKeyboardInteractive {

    String passwd;

    public String getPassword() {
        return passwd;
    }

    public boolean promptYesNo(String str) {
        return true;
    }


    public String getPassphrase() {
        return null;
    }

    public boolean promptPassphrase(String message) {
        return true;
    }

    public boolean promptPassword(String message) {
        passwd = SSH_SERVER_PASSWORD;
        return true;
    }

    public void showMessage(String message) {
        System.out.println("message = " + message);
    }

    public String[] promptKeyboardInteractive(String destination,
            String name, String instruction, String[] prompt, boolean[] echo) {
        if (prompt[0].equals("Password: ")){
            String[] response = new String[1];
            response[0] = SSH_SERVER_PASSWORD;
            return response;
        }
        return null;
    }
}
}

Ответ 5

public String getPassphrase() {         return null;     }

public boolean promptPassphrase(String message) {
    return true;
}

public boolean promptPassword(String message) {
    passwd = SSH_SERVER_PASSWORD;
    return true;
}

public void showMessage(String message) {
    System.out.println("message = " + message);