Perl OpenSSL DH密钥太小错误

Perl OpenSSL DH密钥太小错误,perl,ssl,openssl,Perl,Ssl,Openssl,我正在尝试使用一个简单的PERL脚本连接到一个关闭的服务器——一台空调 #!/usr/bin/perl use 5.10.1; use warnings; use strict; use IO::Socket::SSL; use IO::Socket::SSL qw/debug3/; my $sock = IO::Socket::SSL->new( PeerHost => '192.168.1.4', PeerPort => 2878,

我正在尝试使用一个简单的PERL脚本连接到一个关闭的服务器——一台空调

#!/usr/bin/perl

use 5.10.1;
use warnings;
use strict;
use IO::Socket::SSL;
use IO::Socket::SSL qw/debug3/;
my $sock = IO::Socket::SSL->new(
        PeerHost => '192.168.1.4',
        PeerPort => 2878,
        verify_hostname => 0,   
        SSL_verify_mode => SSL_VERIFY_NONE,
        SSL_verifycn_scheme => undef
) or die "failed connect or ssl handshake: $!,$SSL_ERROR";
print "$sock\n";
现在,这一切都运行得很好,然后我准确地更新了OpenSSL(libssl1.0.0),所有的麻烦都爆发了:

DEBUG: .../IO/Socket/SSL.pm:220: set domain to 2
DEBUG: .../IO/Socket/SSL.pm:1653: new ctx 1984680
DEBUG: .../IO/Socket/SSL.pm:363: socket not yet connected
DEBUG: .../IO/Socket/SSL.pm:365: socket connected
DEBUG: .../IO/Socket/SSL.pm:383: ssl handshake not started
DEBUG: .../IO/Socket/SSL.pm:446: Net::SSLeay::connect -> -1
DEBUG: .../IO/Socket/SSL.pm:1328: SSL connect attempt failed with unknown error error:14082174:SSL routines:SSL3_CHECK_CERT_AND_ALGORITHM:dh key too small

DEBUG: .../IO/Socket/SSL.pm:452: fatal SSL error: SSL connect attempt failed with unknown error error:14082174:SSL routines:SSL3_CHECK_CERT_AND_ALGORITHM:dh key too small
DEBUG: .../IO/Socket/SSL.pm:1328: IO::Socket::INET6 configuration failed error:00000000:lib(0):func(0):reason(0)

DEBUG: .../IO/Socket/SSL.pm:1690: free ctx 1984680 open=1984680
DEBUG: .../IO/Socket/SSL.pm:1698: OK free ctx 1984680
failed connect or ssl handshake: ,IO::Socket::INET6 configuration failed error:00000000:lib(0):func(0):reason(0) at ./spare line 9.
我很乐意使用任何替代软件包来解决这个问题,但我确实需要解决它,因为我无法更新空调上的证书

我考虑过使用LWP和raw Net:SSLeay,但问题似乎出在底层的OpenSSL库中

我考虑过使用LWP和raw Net:SSLeay,但问题似乎出在底层的OpenSSL库中

虽然这是由OpenSSL的更改引起的,但问题实际上是在服务器端。服务器在密钥交换中使用弱DH密钥,而OpenSSL的最新版本强制使用非弱DH密钥,因为存在漏洞

如果服务器支持不使用DH密钥交换的密码,您可以通过限制客户端提供的密码来解决此问题,使其不包含任何DH密码

my $sock = IO::Socket::SSL->new(..., SSL_cipher_list => 'DEFAULT:!DH' ...);
除此之外,像您这样简单地禁用任何验证都是不好的:

    ...
    verify_hostname => 0,   
    SSL_verify_mode => SSL_VERIFY_NONE,
    SSL_verifycn_scheme => undef
例如,
verify_hostname
根本不是有效的参数(这仅适用于LWP)。此外,如果使用
SSL\u verify\u模式
禁用验证,则不需要设置
SSL\u verifycn\u方案,因为没有验证也意味着没有证书主体的验证


但比禁用验证好得多的方法是使用
SSL\u fingerprint
指定所需的证书,从而对自签名或过期的证书进行适当检查。有关更多信息,请参阅IO::Socket::SSL文档。

在我的案例中,唯一的解决方案是在
/etc/SSL/openssl.cnf中设置密码字符串
从


SSL/TLS使用的证书密钥有多长?建议的值是4096或至少2048.echo | openssl s|u client-connect 192.168.1.4:2878 2>/dev/null | openssl x509-text-noout | grep“Public Key”Public Key:(1024位)我知道忽略SSL错误是很糟糕的,可取之处在于它只是用于空调-证书甚至不需要在那里,因为这只能通过内部专用网络完成。不过,感谢您的指点,我会尽快查看它们。添加SSL\u cipher\u list=>'默认值:!DH’to选项工作得很好。虽然这样做有效,但最好在单独的文件中进行更改,
openssl-weak.cnf
,然后仅为遇到此问题的程序设置openssl_-CONF环境变量。
    ...
    verify_hostname => 0,   
    SSL_verify_mode => SSL_VERIFY_NONE,
    SSL_verifycn_scheme => undef
CipherString = DEFAULT@SECLEVEL=2
CipherString = DEFAULT@SECLEVEL=1