【问题标题】:Java 1.7 + JSCH: java.security.InvalidKeyException: Key is too long for this algorithmJava 1.7 + JSCH: java.security.InvalidKeyException: Key is too long for this algorithm
【发布时间】:2016-08-04 04:16:13
【问题描述】:

我正在尝试使用JSCH 将文件上传到远程SFTP 共享。每次我尝试从我的代码中连接到共享时,都会收到如下所示的异常:

com.jcraft.jsch.JSchException: Session.connect: java.security.InvalidKeyException: Key is too long for this algorithm
    at com.jcraft.jsch.Session.connect(Session.java:558) ~[jsch-0.1.51.jar:na]
    at com.jcraft.jsch.Session.connect(Session.java:183) ~[jsch-0.1.51.jar:na]

我在升级到 Java 8 时见过 posts that describe this error,但我们仍在使用 Java 7,而且我对 Java 的加密支持知之甚少,不知道这是否重要。

有人建议安装JCE(Java Cryptography Extensions)来解决这个问题,所以我试了一下,但是在将相应的jar文件复制到/libs/security目录并重新启动应用程序后,我仍然得到同样的错误。我们通过执行this script 确认安装了 JCE,并注意到没有抛出异常。

我还尝试在详细模式下使用sftp 命令从终端连接到远程 SFTP 共享。这是我得到的:

OpenSSH_6.2p2, OSSLShim 0.9.8r 8 Dec 2011
debug1: Reading configuration data /etc/ssh_config
debug1: /etc/ssh_config line 20: Applying options for *
debug1: /etc/ssh_config line 102: Applying options for *
debug2: ssh_connect: needpriv 0
debug1: Connecting to XXXXXXXXXXXXX [XXXXXXXXXXXX] port XX.
debug1: Connection established.
debug3: Incorrect RSA1 identifier
debug3: Could not load "/Users/XXXXX/.ssh/id_rsa" as a RSA1 public key
debug1: identity file /Users/XXXXX/.ssh/id_rsa type 1
debug1: identity file /Users/XXXXX/.ssh/id_rsa-cert type -1
debug1: identity file /Users/XXXXX/.ssh/id_dsa type -1
debug1: identity file /Users/XXXXX/.ssh/id_dsa-cert type -1
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_6.2
debug1: Remote protocol version 2.0, remote software version 3.2.9 SSH Secure Shell
debug1: no match: 3.2.9 SSH Secure Shell
debug2: fd 3 setting O_NONBLOCK
debug3: load_hostkeys: loading entries for host "XXXXXXXXXXXXX" from file "/Users/XXXXX/.ssh/known_hosts"
debug3: load_hostkeys: loaded 0 keys
debug1: SSH2_MSG_KEXINIT sent
debug3: Received SSH2_MSG_IGNORE
debug1: SSH2_MSG_KEXINIT received
debug2: kex_parse_kexinit: diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1
debug2: kex_parse_kexinit: ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,ssh-rsa,ssh-dss
debug2: kex_parse_kexinit: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se
debug2: kex_parse_kexinit: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se
debug2: kex_parse_kexinit: hmac-md5-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-sha1,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96
debug2: kex_parse_kexinit: hmac-md5-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-sha1,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96
debug2: kex_parse_kexinit: none,zlib@openssh.com,zlib
debug2: kex_parse_kexinit: none,zlib@openssh.com,zlib
debug2: kex_parse_kexinit: 
debug2: kex_parse_kexinit: 
debug2: kex_parse_kexinit: first_kex_follows 0 
debug2: kex_parse_kexinit: reserved 0 
debug2: kex_parse_kexinit: diffie-hellman-group1-sha1
debug2: kex_parse_kexinit: ssh-dss
debug2: kex_parse_kexinit: aes128-cbc,3des-cbc,twofish128-cbc,cast128-cbc,twofish-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,twofish192-cbc,twofish256-cbc,arcfour
debug2: kex_parse_kexinit: aes128-cbc,3des-cbc,twofish128-cbc,cast128-cbc,twofish-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,twofish192-cbc,twofish256-cbc,arcfour
debug2: kex_parse_kexinit: hmac-sha1,hmac-sha1-96,hmac-md5,hmac-md5-96
debug2: kex_parse_kexinit: hmac-sha1,hmac-sha1-96,hmac-md5,hmac-md5-96
debug2: kex_parse_kexinit: none,zlib
debug2: kex_parse_kexinit: none,zlib
debug2: kex_parse_kexinit: 
debug2: kex_parse_kexinit: 
debug2: kex_parse_kexinit: first_kex_follows 0 
debug2: kex_parse_kexinit: reserved 0 
debug2: mac_setup: found hmac-md5
debug1: kex: server->client aes128-cbc hmac-md5 none
debug2: mac_setup: found hmac-md5
debug1: kex: client->server aes128-cbc hmac-md5 none
debug2: dh_gen_key: priv key bits set: 122/256
debug2: bits set: 496/1024
debug1: sending SSH2_MSG_KEXDH_INIT
debug1: expecting SSH2_MSG_KEXDH_REPLY
debug3: Received SSH2_MSG_IGNORE
debug1: Server host key: DSA XXXXXXXXXXXXXXXXXXXXXXXX
debug3: load_hostkeys: loading entries for host "XXXXXXXXXXXXX" from file "/Users/XXXXX/.ssh/known_hosts"
debug3: load_hostkeys: loaded 0 keys
debug3: load_hostkeys: loading entries for host "XXXXXXXXXXXX" from file "/Users/XXXXX/.ssh/known_hosts"
debug3: load_hostkeys: loaded 0 keys
    The authenticity of host 'XXXXXXXXXXXXX (XXXXXXXXXXXX)' can't be established.
    DSA key fingerprint is XXXXXXXXXXXXXXXXXXXXXXXX.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added 'XXXXXXXXXXXXX,XXXXXXXXXXXX' (DSA) to the list of known hosts.
debug2: bits set: 516/1024
debug1: ssh_dss_verify: signature correct
debug2: kex_derive_keys
debug2: set_newkeys: mode 1
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug3: Received SSH2_MSG_IGNORE
debug2: set_newkeys: mode 0
debug1: SSH2_MSG_NEWKEYS received
debug1: Roaming not allowed by server
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug3: Received SSH2_MSG_IGNORE
debug2: service_accept: ssh-userauth
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug2: key: /Users/XXXXX/.ssh/id_rsa (0x7f8e28500a10),
debug2: key: /Users/XXXXX/.ssh/id_dsa (0x0),
debug3: Received SSH2_MSG_IGNORE
debug1: Authentications that can continue: publickey,password
debug3: start over, passed a different list publickey,password
debug3: preferred publickey,keyboard-interactive,password
debug3: authmethod_lookup publickey
debug3: remaining preferred: keyboard-interactive,password
debug3: authmethod_is_enabled publickey
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /Users/XXXXX/.ssh/id_rsa
debug3: send_pubkey_test
debug2: we sent a publickey packet, wait for reply
debug3: Received SSH2_MSG_IGNORE
debug1: Authentications that can continue: password
debug3: start over, passed a different list password
debug3: preferred publickey,keyboard-interactive,password
debug3: authmethod_lookup password
debug3: remaining preferred: ,keyboard-interactive,password
debug3: authmethod_is_enabled password
debug1: Next authentication method: password

如果我正确读取输出(我可能不是),握手过程决定使用aes128-cbc 进行密钥交换,使用hmac-md5 进行实际会话加密。根据the JSCH documentation(尽管可能很小),这两种算法都受支持。

我可以使用sftp 命令行实用程序和 FileZilla 连接到此共享,因此问题可能与 JSCH 或我的 Java 配置有关,但我不知道是什么.

Java 版本:

java version "1.7.0_71"
OpenJDK Runtime Environment
OpenJDK 64-Bit Server VM (build 24.65-b04, mixed mode)

JSCH 版本:

<dependency>
    <groupId>com.jcraft</groupId>
    <artifactId>jsch</artifactId>
    <version>0.1.51</version>
</dependency>

提前致谢!

编辑: 看起来 a bug for this exact behaviour 是针对 JDK 提出的,但没有解决就关闭了。 JSCH 的维护人员和 JDK 开发人员之间也有 an email thread 讨论该问题,但没有解决方案。

【问题讨论】:

  • 哇。我突然出现在这里推荐 JCE,但看起来你已经完成了你的功课(无论如何这不应该是问题,但都是一样的)。您是否有机会使用 Oracle Java(而不是 OpenJDK)7 进行尝试?我并不是要含糊其辞,但过去我在 OpenJDK 上运气不佳。在这一点上,我认为 Oracle Java 至少值得一试。您可能必须将 JCE 安装到其中(我承认我在这里抓住了稻草。只是希望我能提供帮助)
  • 一些澄清:(1)您没有安装JCE,它已经在Java包中。您安装了“无限强度策略”,它是 JCE 的 插件。仅当所需/协商的对称加密超过 128 位时才会有所不同,而您的情况似乎并非如此。 (2) 您的 sftp 握手选择 aes128-cbc 用于 加密hmac-md5 用于 完整性检查; key-exchange 是 Diffie-Hellman,主机身份验证是 DSA,客户端身份验证似乎是密码。 ...
  • ... (3) 使用的 DH 和 DSA 组似乎是 1024 位,这对于 Java 7 应该没问题。但如果调试输出不准确和可靠,它可能会有所帮助获取网络跟踪,尤其是使用 Wireshark 或类似方法的 jsch 尝试,以确保并准确查看失败的时间。或者,如果您可以使用 Java 8 进行测试,则扩展了 DH 和 DSA 的限制(尽管出于其他原因您可能需要也可能不想要 8)。
  • 感谢@dave_thompson_085 的澄清。你能告诉我哪个步骤抱怨密钥太长吗?我链接的另一篇 SO 帖子似乎表明目标服务器使用的 DSA 密钥长度 > 1024 位。 Java 是否不支持这个密钥长度,或者我可以做一些配置来允许它吗?
  • 在进一步检查时我部分错了。 Java7 将 DH 和 DSA generation 限制为 1024,但这与您的例外情况不同,并且 ssh 握手不会生成 DSA(仅使用它)。你确定你没有运行 j8,或者(不知何故)j8 提供者? AFAICT 此异常消息在 j7 中根本不存在。我忘记的是 SSH 仍然使用 DSA>1024 的 SHA1,而不是更好匹配的 SHA224 和 SHA256,而且似乎 Java8 决定阻止这种组合。您现在指出的错误报告和电子邮件明确说明了这一点,我同意甲骨文似乎拒绝改变。 ...

标签: java java-7 sftp jsch jce


【解决方案1】:

我们最终将 JSCH 换成了 SSHJ。它依赖于 BouncyCastle 加密库而不是 Java 的内置加密包,并且能够毫无问题地连接到我们的服务器。

【讨论】:

    【解决方案2】:

    您可以强制 JSCH 使用 SHA256 而不是 SHA1 和 keysize &gt; 1024(JSSE 不再允许),如下所示:

    java.util.Properties configuration = new java.util.Properties();
    configuration.put("kex", "diffie-hellman-group-exchange-sha256");           
    configuration.put("StrictHostKeyChecking", "no");
    session.setConfig(configuration);
    

    【讨论】:

    • “JSSE 不再允许”指的是什么?可以提供参考吗?
    【解决方案3】:

    实际上,针对 JDK 提交的 bug for this behaviour 并未关闭 - 关闭它的决定已恢复,并且在几天后修复。它后来被向后移植,所以升级到Java SE 8u45(或更高版本)也可以解决问题

    【讨论】:

      【解决方案4】:

      安装 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files click here to download

      将 local_policy.jar 和 US_export_policy.jar 替换为以下位置的不受限制的策略文件: Java\jre7\lib\security\

      我在使用 ibm jre 1.5 版和 tomcat 加密数据时遇到了类似的问题。

      【讨论】:

      • 请完整阅读原帖。我们尝试安装 Unlimited Strength Jurisdiction Policy Files,但没有帮助
      猜你喜欢
      • 2017-08-26
      • 1970-01-01
      • 2018-12-12
      • 2012-06-08
      • 1970-01-01
      • 2023-03-27
      • 2020-12-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多