首页 文章

使用Java 1.4.2在jsch-0.1.42中“验证失败”

提问于
浏览
12

我有这个简单的Java程序,它使用Jsch连接到SFTP服务器 .

连接失败,Java 1.4.2上出现“Auth fail”异常,但它在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 密钥文件与私钥存在于同一目录中 .

连接 Logger 时,我在异常之前看到以下消息(发生在 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>

我已经为1.4 VM安装了Java Cryptography Extensions(JCE) .

可能是这个问题的根源是什么?

5 回答

  • 4

    您是否尝试过使用Open SSH密钥? jsch使用Open SSH密钥格式 . 您可以将现有的转换为Open SSH格式 . 具体方法如下:使用putty keygen并加载现有密钥 . 系统可能会提示您输入密码进行解密 . 之后,单击上面的转换选项,然后选择“导出OpenSSH密钥” . 在上面的程序中使用这个新生成的密钥 . 希望这可以帮助 .

  • -2

    我对jsch的问题一直是权限问题 . 所以我会做以下事情来消除它们作为问题

    • 确保可以使用生成的密钥在命令行上ssh到远程 .

    • 传入密码并确保可以连接到遥控器 .

    • 在本地和远程good ssh summary上检查目录的权限 .

    • 尝试将本地主机用作远程 .

    无法下载源代码并在调试会话中逐步执行 .

  • 3

    public String getPassphrase(){return null; public boolean promptPassphrase(String message){
    返回true;
    }

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

    public void showMessage(String message){
    System.out.println(“message =”message);

  • 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的网站上,现在我不知道它在哪里可以找到 .

    你可以阅读更多in this article

    编辑:经过一些研究,我发现我的答案是不正确的 .

    Java 1.4不支持超过2048字节长度的RSA密钥BUG 4524097

  • -3

    This code works fine...

    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;
        }
    }
    }
    

相关问题