【问题标题】:How to properly obtain SAN using Perl library Crypt::OpenSSL::X509如何使用 Perl 库 Crypt::OpenSSL::X509 正确获取 SAN
【发布时间】:2022-01-07 11:32:28
【问题描述】:

我之前一直在使用 Crypt::X509,但现在我将我的代码移植到更新的支持库 Crypt::OpenSSL::X509。证书中最重要的字段是 CN 和 SAN,我希望有一个简单的调用,例如:

use Crypt::X509;
print $x509->$cert_hr->SubjectAltName;

但是我不得不使用繁琐的代码:

use Crypt::OpenSSL::X509;
my $ext = $x509->extensions_by_oid();
print ${$ext}{'2.5.29.17'}->value();

但更糟糕的是,返回的字符串有寄生的“。”在里面,我需要创建一些智能正则表达式来安全地清理它。

我觉得我错过了一些简单的东西。是否有其他函数或库?

编辑:测试结果:只要您更新到最新版本的库,建议的 Timothy 解决方案就可以工作。无法添加评论,也不能按“接受的答案”。稍后会再次访问。

【问题讨论】:

  • “还有其他函数或库吗?” - 看看IO::Socket::SSL::Utils,它包含将证书解析为散列、从散列创建新证书的函数……它还可以轻松访问subjectAltNames

标签: perl ssl x509 san


【解决方案1】:

这是一个如何使用 Crypt::OpenSSL::X509 和 Convert::ASN1 的示例,我必须说它花费的时间比我预期的要多:

use Crypt::OpenSSL::X509;
use Convert::ASN1;
 
my $x509 = Crypt::OpenSSL::X509->new_from_file('google.pem');
my $ext = $x509->extensions_by_oid();
my $pdu = ${$ext}{'2.5.29.17'}->value();
$pdu =~ s/#//g;

my @san = get_san($pdu);

print "Size: ", scalar @san, "\n";

foreach (@san) {
    print "$_\n";
}

sub get_san {
    my $bin_data = join '', pack 'H*', @_;
    $asn = Convert::ASN1->new();

    my $ok = $asn->prepare(q<
        DNSName ::=  
            [2]
            IA5String
        SubjectAltName ::= SEQUENCE OF
            DNSName
    >);
    die "*** Could not prepare definition: ".$asn->error()
        if !$ok;

    my $top = $asn->find("SubjectAltName")
        or die $asn->error;
    $out = $top->decode($bin_data)
        or die "can't decode SubjectAltName: ".$top->error;

    return @$out;
}

https://github.com/dsully/perl-crypt-openssl-x509/pull/92 实现了这个的扩展形式,它应该适用于大多数 X509 证书

【讨论】:

  • 不起作用。添加了 2 行进行调试,没有其他任何更改。 ` print("get_san 收到的参数:".join("",@_)."\n"); print "bin_data==HEX(".sprintf("%v02X", $bin_data).")\n"; ` 结果: ` # openssl x509 -in google.pem -text | grep "v3 Subject A" -A 1 X509v3 Subject Alternative Name: DNS:www.google.com # ./stack_overflow.pl 为 get_san 收到的参数:0...www.google.com bin_data==HEX (0E.EE.00.0E.08.80.5E.EC.86) 无法解码联系人:在 /usr/share/perl5/vendor_perl/Convert/ASN1/_decode.pm 第 64 行解码错误。`
  • 对不起,不知道如何在 cmets 中进行格式化。
  • 奇怪,我可能有一个旧版本。让我再看看
  • 你能检查模块版本 perl -MCrypt::OpenSSL::X509 -I blib/lib/ -I blib/arch/ -e 'print $Crypt::OpenSSL::X509::VERSION , "\n";' perl -MConvert::ASN1 -I blib/lib/ -I blib/arch/ -e 'print $Convert::ASN1::VERSION, "\n";'该函数需要一长串十六进制字符,例如:30820935820C....,它将填满屏幕。如果您使用来自 metacpan 的证书: get_san 收到的参数:300E820C6D6574616370616E2E6F7267 bin_data==HEX(30.0E.82.0C.6D.65.74.61.63.70.61.6E.2E.6F.72.67) 大小:1个metacpan.org
  • 另见github.com/dsully/perl-crypt-openssl-x509/pull/92 可能需要一段时间才能被 Crypt::OpenSSL::X509 接受(如果可以的话),但我将其扩展为适用于各种 SAN 类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-31
  • 1970-01-01
  • 2012-06-08
  • 2015-02-26
  • 2011-03-28
相关资源
最近更新 更多