java - DHGEX在Java 8下使用2048位 key 失败,但是在1024位 key 下成功

标签 java public-key-encryption jsch diffie-hellman

我正在使用JSCH 0.1.53连接到远程SSH服务器,该服务器使用1024位RSA密钥。当我们还使用1024位RSA密钥时,我们能够成功连接到远程服务器,但是当我们生成更强的2048位密钥时,我们将停止连接。我们收到一条错误消息,内容为“素数大小必须是64的倍数,并且只能在512到2048之间变化”,该错误消息源自对DHGEX.java(Diffie-Hellman Group EXchange)的调用。

我们正在运行Java 1.8,并且错误消息正确地将最大位大小指定为2048,因此问题不在于Java 1.6和1.7中的1024位的JCE密钥限制。我们已经通过openssl rsa -text -noout -in id_rsa和ssh-keygen -lf id_rsa.pub确认了我们的私钥和公钥实际上都是2048位。

既然一切看起来都很好,我开始在JSCH代码中添加调试行并重新编译JAR,最终我可以确定在密钥交换期间传递给我们的模数实际上是2047位长。现在,长度为2047位并不意味着您没有生成2048位密钥,也没有强度比实际包含2048位的密钥强,这仅意味着您碰巧得到了两个素数相乘的结果到第一个位为0的对象。因此,这是预期的行为(有时),并且JCE检查应该是(n%64 == 0 || n%64 == 63)。但是JCE确实很棘手,因此它拒绝此密钥,因为它的长度不合法。

基于此,我想我已经找到了问题:远程服务器生成了一个仅包含2047位的2048位密钥,因此他们只需要生成一个新密钥(并继续这样做,直到获得真正的密钥即可)。 2048位)。但是,当我向他们的管理员询问时,他们坚持认为他们使用的是1024位密钥,而这实际上就是通过SSH进行访问后在known_hosts文件中得到的。毕竟,这似乎并不是原因。

因此,我开始记录包含它们发送给我们的缓冲区的内容,并提取p和g值(模数和组),然后发现在短短几天的几天内测试中,有33个不同的模量值,并且在以base 64或base 10进行编码时,所有字符的区别仅在于最后几个字符。模块值被重用,有时仅被重用一次,有时被打十二次,但是有很多不同的值,因此键既不会一次性生成,也不会一次生成并永远重复使用。

这是(在任何情况下,服务器发送许多非常接近的数字的不同密钥,有一些重用,但有许多唯一值)预期行为,尤其是当客户端使用2048位密钥但服务器使用密钥时的预期行为吗? 1024位密钥?自上周我开始调查以来,我对Diffie-Hellman小组交流一无所知,所以也许这就是它的工作方式,但对我来说却很奇怪。

另外,SSH标准是否规定了有关在这种情况下应如何生成密钥的任何内容?我还没有发现远端正在使用什么SSH服务器(我怀疑是OpenSSH,但不确定,也不知道是哪个版本),但是我希望可能有一些标准可以强制使用使用与请求的大小相同(在1 ^(n-1)和1 ^ n-1之间)的密钥,并且远程服务器可以选择强制执行此密钥,或者我可以针对它们提交错误让他们改变行为。我可能还会针对JDK提交一个bug,以允许n-1位的键,第一位的填充为0。

任何人都可以给出的任何指导将不胜感激。

我还将这个问题发布到JSCH邮件列表中:https://sourceforge.net/p/jsch/mailman/message/35042955/

更新:

进一步阅读后,我相信Diffie-Hellman的前向保密特性意味着在每个会话中将使用不同的素数(通常来自存储在/ etc / ssl / moduli等位置的预生成集)(素数:https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange#Forward_secrecy),并且素数实际使用的不是RSA密钥(来源:https://stackoverflow.com/a/23346185/1247705),因此不再需要看到许多不同的p值这一事实。我仍然惊讶于它们的价值如此之高,但也许这也是意料之中的。

另一端使用Solaris SSH 1.1.4(据我所知它基于OpenSSH)作为SSH守护程序。是否期望该守护程序作为Diffie-Hellman密钥交换的一部分传递2047位素数,并且可以做些什么使其发送2048位素数呢?

最佳答案

我们通过以下方式修复了类似的症状:

Security.insertProviderAt(new BouncyCastleProvider(), 1)

我们使用的是Jsch 0.1.54,看到了:

java.security.InvalidAlgorithmParameterException:DH密钥大小必须是64的倍数,并且只能在512到4096(含)范围内。不支持特定的密钥大小2047

可能相关的是JDK-8164963: InvalidAlgorithmParameterException prime size issue after JDK upgrade with JSCH libraries

关于java - DHGEX在Java 8下使用2048位 key 失败,但是在1024位 key 下成功,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36869631/

相关文章:

java - boolean 返回问题/从放入数组的方法中获取因素

java.util.ArrayList 无法转换为 myclass - gson

ssl - 为什么 SSL 架构有两个截然不同的功能?

c - C语言使用公钥文件加密数据

java - 通过java ssh,将错误存储在变量中

linux - 在远程服务器上通过 SSH (JSch) 运行 Linux GUI/GTK 应用程序

java - 两个选项卡之间的 session 问题

java - jtable 单元格中的按钮和文本框对齐

windows - 无法在 Windows 上从/usr/local/ssl/openssl.cnf 加载配置信息

java - 使用 JSch 无需用户名或密码即可连接到服务器