使用perl Crypt :: X509从证书中提取数据

时间:2016-08-17 08:02:46

标签: perl ssl x509 pem

我正在尝试使用Crypt :: X509库从.pem证书中提取数据,但是在对象构造中出现错误。 这是我正在做的事情: 1.阅读.pem文件的内容:

my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
   $atime,$mtime,$ctime,$blksize,$blocks) = stat $s_filename;
open FILE, "<$s_filename" or die "no such file";
binmode FILE;
my $pem_cert;
read FILE, $pem_cert, $size;
close FILE; 

2。从base64解码内容以接收DER格式的内容。这样做是因为Crypt :: X509库的CPAN文档声明它需要传递:

  

包含要解析的DER格式证书的变量

my $der = MIME::Base64::decode($pem_cert);
  1. 调用Crypt :: X509构造函数并检查错误:
  2. my $oref_x509= Crypt::X509->new(cert=>$der); if ( $oref_x509->error ) { warn "Error on parsing certificate: ", $oref_x509->error; }

    我收到以下错误:

    Error on parsing certificate: decode error 04<=>30 0 8  at ..<path>../Convert/ASN1/_decode.pm line 113.  
    

    我尝试过其他证书,但错误是一样的。

2 个答案:

答案 0 :(得分:2)

使用MIME :: Base64 :: decode将证书从PEM转换为DER时,您需要删除PEM标题和预告片,即代替解码

-----BEGIN CERTIFICATE-----
MIICVTCCAbegAwIBAgIELwBe7DAKBggqhkjOPQQDAjAaMRgwFgYDVQQDDA9mb28u
....
-----END CERTIFICATE-----

你应该只解码base64部分:

MIICVTCCAbegAwIBAgIELwBe7DAKBggqhkjOPQQDAjAaMRgwFgYDVQQDDA9mb28u
....

由于-----BEGIN CERTIFICATE-----等包含有效的base64字符,因此它们将用于解码,并且无效字符将被忽略。

答案 1 :(得分:0)

您不需要以二进制模式打开base64编码文件,因为它已经是8位清理。但是DER文件是二进制文件,因此在该实例中使用binmode()是正确的。

我认为问题在于你正在尝试的证书 解析实际上是PEM格式而不是DER格式。如果你看看Stephan的answer,他会详细说明差异(主要是在删除PEM页眉/页脚后,DER是PEM的base64解码变体)。

如果您有权访问openssl,可以使用以下命令将其从PEM转换为DER:

openssl x509 -inform PEM -outform DER -in cert.pem -out cert.der

(其中cert.pem是输入证书的名称)。

然后你应该能够使用Crypt :: X509。

如果我尝试解析PEM格式文件,或者base64解码并解析它,我会得到同样的错误:

Failed to parse cert: decode error 04<=>30 0 8  at /usr/local/share/perl5/Convert/ASN1/_decode.pm line 113.

但是,如果我使用DER版本,它可以正常工作:

use warnings 'all';
use strict;

use Crypt::X509;

my $file = 'cert.der';
my $size = (stat $file)[7];

my $cert;
open(my $fh, '<', $file) or die "failed to open cert: $!";
binmode($fh);
read $fh, $cert, $size;
close($fh);

my $x509 = Crypt::X509->new(cert => $cert);
if($x509->error) {
    die "Failed to parse cert: " . $x509->error;
}