0

我正在尝试使用 perl Convert::ASN1 解码 asn.1 OCSP 请求我得到的十六进制转储如下:

30773075304E304C304A300906052B0E03021A050004146283D6C38BF724E2EE10A7D2829A4F906E48F3F2041423490CF9B7D39B1BD93A60A2A67877894782E96F021100B1C544D7AFA4039D4F482BDDEE975E38A2233021301F06092B060105050730010204120410ABE72957E85AE50E8B9628DB495BD5D5

我使用在线工具验证它是一个有效的asn.1编码,结构如下

SEQUENCE {
   SEQUENCE {
      SEQUENCE {
         SEQUENCE {
            SEQUENCE {
               SEQUENCE {
                  OBJECTIDENTIFIER 1.3.14.3.2.26 (id_sha1)
                  NULL 
               }
               OCTETSTRING 6283D6C38BF724E2EE10A7D2829A4F906E48F3F2
               OCTETSTRING 23490CF9B7D39B1BD93A60A2A67877894782E96F
               INTEGER 0x00B1C544D7AFA4039D4F482BDDEE975E38
            }
         }
      }
      [2] {
         SEQUENCE {
            SEQUENCE {
               OBJECTIDENTIFIER 1.3.6.1.5.5.7.48.1.2
               OCTETSTRING 0410ABE72957E85AE50E8B9628DB495BD5D5
            }
         }
      }
   }
}

我把十六进制打包解码

my $data = "30773075304E304C304A300906052B0E03021A050004146283D6C38BF724E2EE10A7D2829A4F906E48F3F2041423490CF9B7D39B1BD93A60A2A67877894782E96F021100B1C544D7AFA4039D4F482BDDEE975E38A2233021301F06092B060105050730010204120410ABE72957E85AE50E8B9628DB495BD5D5";
my $asn1Val=pack("H*",$data);

我由此创建了我的 asn1.1 架构

my  $asn = Convert::ASN1->new;
$asn->prepare( q<
   OCSPRequest     ::=     SEQUENCE {
       tbsRequest                  TBSRequest,
       optionalSignature   [0]     EXPLICIT Signature OPTIONAL
   }

   TBSRequest      ::=     SEQUENCE {
       version             [0]     EXPLICIT Version OPTIONAL,   -- DEFAULT v1
--       requestorName       [1]     EXPLICIT GeneralName OPTIONAL,
       requestList                 SEQUENCE OF Request,
       requestExtensions   [2]     EXPLICIT Extensions OPTIONAL
   }

   Request         ::=     SEQUENCE {
       reqCert                     CertID,
       singleRequestExtensions     [0] EXPLICIT Extensions OPTIONAL
   }

   AlgorithmIdentifier  ::=  SEQUENCE  {
        algorithm           OBJECT IDENTIFIER,
        parameters          ANY DEFINED BY algorithm OPTIONAL
   }

   CertID          ::=     SEQUENCE {
       hashAlgorithm        AlgorithmIdentifier,
       issuerNameHash       OCTET STRING, -- Hash of issuer's DN
       issuerKeyHash        OCTET STRING, -- Hash of issuer's public key
       serialNumber         CertificateSerialNumber
   }

   CertificateSerialNumber  ::=  INTEGER

   Extension  ::=  SEQUENCE  {
        extnID      OBJECT IDENTIFIER,
        critical    BOOLEAN OPTIONAL, -- DEFAULT FALSE,
        extnValue   OCTET STRING
                    -- contains the DER encoding of an ASN.1 value
                    -- corresponding to the extension type identified
                    -- by extnID
        }

   Extensions  ::=  SEQUENCE OF Extension

   Signature       ::=     SEQUENCE {
       signatureAlgorithm   AlgorithmIdentifier,
       signature            BIT STRING
--,       certs             [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL
   }

   Version     ::=  INTEGER  -- {  v1(0) }

>)

当我尝试对上述内容进行解码时,它有时会起作用,有时会失败。

asn_dump($data); # This works fine
my $decoded=$asn->decode($data) or print $asn->error();
print Dumper ($decoded); 

我认为架构是正确的,但解码失败我无法在网上找到很多示例。

4

1 回答 1

3

您在这里提出的重要观点是您说“它有时有效,有时失败”。对我来说,这是你没有使用 find() 来告诉 Convert::ASN1 在你的定义中从哪里开始的线索。

如果您准备的 ASN.1 中有多个宏(一个 typedef),则必须使用 find()。然后使用 find() 生成的对象来执行 decode()。还要记住,始终检查 find() 和 decode() 的返回状态;如果 undef 则错误将出现在您使用的对象的 ->error() 中。

my $asn = new Convert::ASN1;
my $ok = $asn->prepare( q< ...your asn.1 definition here... >);
die "*** Could not prepare definition: ".$asn->error()
  if !$ok;
my $top = $asn->find("OCSPRequest");
die "*** Could not find top of structure: ".$asn->error()
  if !$top;
my $result = $top->decode($your_pdu);   # Use $top, NOT $asn !
die "*** Could not decode PDU: ".$top->error()
  if !$result;

这有点猜测,因为您的问题没有给我足够的背景信息,但我希望它有所帮助。

于 2015-08-13T03:26:56.827 回答