Dem*_*ess 0 encryption error-handling perl cryptography
在我之前的问题中,建议我使用该模块Crypt::OpenSSL::RSA导出和发送RSA密钥.但是,我发现这个模块似乎无法处理非致命错误,因此只需发送格式错误的字符串(即不是RSA密钥),服务器程序在尝试使用创建新对象时就会崩溃它与消息:
server.pl第46行无法识别的密钥格式
第46行包含代码
$clients{$cur_client}->{pub_key} = Crypt::OpenSSL::RSA->new_public_key($message) or do {
server_log "Bad key exchange, dropping user $address:$port...";
delete $clients{$cur_client};
next;
}; # Key exchange
Run Code Online (Sandbox Code Playgroud)
我该如何解决?
您需要使用BLOCK形式eval来防止程序在引发异常时死亡.不幸的是,裸露的使用eval充满了尴尬的角落情况,最好使用Try::Tiny处理这些的模块
为了达到你的问题代码的目的,你会写这样的东西.显然,您必须为变量提供有用的数据
要注意这一点很重要的是try和catch是子程序.这意味着你之后需要一个分号catch,而你不能next在内,catch因为你不能在子程序中做到这一点.您必须保留某种状态集,以便后续代码可以执行任何必要的操作,在这种情况下,我只检查是否$clients{$cur_client}仍然存在 - catch如果出现问题,它将被例程删除
同样值得解释的die是,$_该catch例程中的字符串可用,因此您可以检查失败的原因.在这种情况下,catch期望只处理unrecognized key format错误,因此代码检查这确实是失败的原因.如果没有,那么它会发出另一个,die $_以反映发生了未处理的错误
use strict;
use warnings 'all';
use Crypt::OpenSSL::RSA;
use Try::Tiny;
my %clients = ( aa => {} );
my $message = 'xxx';
my ($address, $port) = qw/ 127.0.0.1 80 /;
for my $cur_client ( keys %clients ) {
try {
$clients{$cur_client}{pub_key} = Crypt::OpenSSL::RSA->new_public_key($message);
}
catch {
if ( /unrecognized key format/ ) {
server_log("Bad key exchange, dropping user $address:$port...");
delete $clients{$cur_client};
}
else {
die $!;
}
};
next unless exists $clients{$cur_client};
# More handling of $cur_client in the case that
# the call to new_public_key succeeds
}
sub server_log {
print "Logging: $_[0]\n";
}
Run Code Online (Sandbox Code Playgroud)