先做下名词解释和说明
客户端 B
服务端 S
DH算法 迪菲赫尔曼算法
TLS SSL协议的升级(建议将SSL协议升级到TLS1.0或者更高版本)
继续之前,建议一定先仔细看下SSL通信过程和DH算法原理,此处不再赘述
最近项目中遇到的问题:抓取ssl通信过程中,发现返回的Pubkey长度96位,偶尔为95位,当为95位时候就会报错,如下图(工具为Wireshark)
再查阅了相关资料后,多次抓包并确认最终问题为:DH算法问题
客户端与服务器端会动态协商参数,服务端在计算参数时,如果SSL/TLS握手过程中,假如选中了诸如TLS_DHE_RSA_WITH_AES_128_CBC_SHA
(这是加密套件,执行openssl ciphers -v 可以看下系统支持的ssl加密套件有哪些)
这样使用deffie-hellman密钥的cipher,那么在deffie-hellman密钥交换过程中会使用的一个P参数(prime number),服务器侧提供的P参数在JDK8之前都只用了768bit的长度,小于1024bit存在安全漏洞可导致logjam attack,会被最新本版的浏览器和BoringSSL拒绝。
推荐两种解决方案:
方案1:推荐RSA或者ECDHE算法(客户或者服务端任意一端删除DH算法即可)
方案2:即使一定要用DH算法,必须控制位数在2048位以上(涉及到JDK版本升级,至少JDK1.7以上)
参考资料:
1.DH文档说明:https://tools.ietf.org/html/rfc5246#section-7.4.3
2.Server Key Exchange
密钥交换阶段(可选步骤),之所以说是可选步骤,是因为只有在下列场景下这个步骤才会发生
1) 协商采用了RSA加密,但是服务端的证书没有提供RSA公钥
2) 协商采用了DH加密,但是服务端的证书没有提供DH参数
3) 协商采用了fortezza_kea加密,但是服务端的证书没有提供参数
总结来说,"Server Key Exchange"这个步骤是对上一步"Certificate"的一个补充,为了让整个SSL握手过程能正常进行
3.类似问题和网络解答:
http://security.stackexchange.com/questions/104845/dhe-rsa-pubkey-length-in-tls-1-2
[解答中这一段值的关注]
In all your examples, all DH keys are of size "1024 bits", exactly. In DH, there are the parameters (modulus p, generator g), the private key (x) and the public key (y). The relation is y = gx mod p.
The "key length" is the size of the prime p. In all your cases, p lies between 21023 and 21024, so it is a "1024-bit integer" and this is the size of the DH key pair. Now, the "public key" itself is the integer y which lies between 1 and p-1; in particular, nothing forces y to be larger than 21023, and this is not a problem. The "pubkey length" field is the size, in bytes, of the encoded value y (in big-endian unsigned notation). Depending on the exact value of p, it is expected that between 1/256th and 1/128th of all DH public keys will need only 127 bytes for their encoding. In your last example, the value y is encoded over 127 bytes, the first one being 06, which implies that y is technically a 1011-bit integer; the DH key length is still 1024 bits since that is the size of p.
Thus, the "pubkey length" relates to the public key length as in "length of the encoding of y", but NOT as in "length that tells whether the key can be broken by powerful attackers".
Apparently, some system in your setup (the client, or some router/firewall in between the client and server -- maybe the FIN you observe on the server is not sent by the client itself) is confused and fails to distinguish the two notions of "pubkey length". Configuring your F5 to use a larger modulus for DH may work around the problem, and could be considered as a good idea anyway (1024-bit DH is not yet breakable, but theoretically you would like to use 1024-bit DH no more than you would accept to use 1024-bit RSA).