OpenSSL DH键太小错误

jsn*_*wlr 5 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,
        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";
Run Code Online (Sandbox Code Playgroud)

现在,这一切都运行良好,然后我确切地更新了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.
Run Code Online (Sandbox Code Playgroud)

我很乐意使用任何替代方案来解决这个问题,但我确实需要绕过它,因为我无法更新空调上的证书......

我已经研究过使用LWP和raw Net:SSLeay,但问题似乎是在底层的OpenSSL库中.

Get*_*toX 13

就我而言,唯一的解决方案是将 CipherString 设置为/etc/ssl/openssl.cnf from

CipherString = DEFAULT@SECLEVEL=2
Run Code Online (Sandbox Code Playgroud)

CipherString = DEFAULT@SECLEVEL=1
Run Code Online (Sandbox Code Playgroud)

  • 我的 openssl.cnf 没有 CipherString 选项 (7认同)
  • 虽然这有效,但最好在单独的文件“openssl-weak.cnf”中进行更改,然后仅为遇到此问题的程序设置 OPENSSL_CONF 环境变量。 (6认同)

Ste*_*ich 6

... SSL3_CHECK_CERT_AND_ALGORITHM:dh key too small
Run Code Online (Sandbox Code Playgroud)

我已经研究过使用LWP和raw Net:SSLeay,但问题似乎是在底层的OpenSSL库中.

虽然它是由OpenSSL的更改引起的,但问题实际上是在服务器端.服务器在密钥交换中使用弱DH密钥,并且由于Logjam攻击,最新版本的OpenSSL强制执行非弱DH密钥.

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

my $sock = IO::Socket::SSL->new(..., SSL_cipher_list => 'DEFAULT:!DH' ...);
Run Code Online (Sandbox Code Playgroud)

除此之外,简单地禁用任何验证都是不好的:

    ...
    verify_hostname => 0,   
    SSL_verify_mode => SSL_VERIFY_NONE,
    SSL_verifycn_scheme => undef
Run Code Online (Sandbox Code Playgroud)

例如,verify_hostname根本不是有效参数(仅适用于LWP).此外,SSL_verifycn_scheme如果禁用验证,则无需设置,SSL_verify_mode因为没有验证也意味着不验证证书主题.

但是,比禁用验证更好的方法是使用SSL_fingerprint指定您期望的证书,从而对自签名证书或过期证书进行适当的检查.有关详细信息,请参阅IO :: Socket :: SSL文档中的常见用法错误.