代码之家  ›  专栏  ›  技术社区  ›  Kevin G.

Convert::ASN1解码错误

  •  0
  • Kevin G.  · 技术社区  · 6 年前

    我一定错过了一些很明显的东西。我可以使用诸如 http://asn1-playground.oss.com/ ,但我在Perl的Convert::ASN1的基本用法方面遇到了问题。知道我错过了什么吗?

    use strict;
    use warnings;
    use Convert::ASN1;
    use feature 'say';
    
    # example from:
    # http://www.oss.com/asn1/resources/asn1-made-simple/introduction.html
    
    my $hex_data = '3018800A4A6F686E20536D697468810A39383736353433323130';
    my $bin_data = join '', pack 'H*', $hex_data;
    
    Convert::ASN1::asn_dump($bin_data);
    # prints:
    #    0000   24: SEQUENCE {
    #    0002   10:   [CONTEXT 0]
    #    0004     :     4A 6F 68 6E 20 53 6D 69 74 68 __ __ __ __ __ __ John Smith
    #    000E   10:   [CONTEXT 1]
    #    0010     :     39 38 37 36 35 34 33 32 31 30 __ __ __ __ __ __ 9876543210
    #    001A     : }    
    
    my $asn = Convert::ASN1->new;
    $asn->prepare(<<ASN1) or die $asn->error;    
        Contact ::= SEQUENCE {
            name VisibleString,
            phone NumericString
        }
    ASN1
    
    my $asn1_node = $asn->find('Contact') 
        or die $asn->error;
    
    my $payload = $asn1_node->decode($bin_data) 
        or die "can't decode Contact: ".$asn1_node->error;
    # prints:
    #    can't decode Contact: decode error 80<=>1a 2 4 name
    

    支持YaFred下面的答案,这就是80和81在编码字符串中的位置:

    SEQ length=24 ** l=10  J  o  h n   S m i t h  ** l=10  9 8 7 6 5 4 3 2 1 0
    30  18        80 0A    4A 6F 686E20536D697468 81 0A    39383736353433323130
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   YaFred    6 年前

    也许这很容易

    $asn->prepare(<<ASN1) or die $asn->error; 
    My-Module DEFINITIONS AUTOMATIC TAGS ::=
    BEGIN   
            Contact ::= SEQUENCE {
                name VisibleString,
                phone NumericString
            }
    END
        ASN1
    

    如果从ASN开始解释,有点长。1.

    您没有提供标记上下文(类型联系人应该是模块的一部分)。所以,工具正在做出选择。。。

    您显示的hexa是使用自动标记编码的结果

    这两个字符串的标记分别为“80”(上下文标记0=1000 0000)和“81”(上下文标记1=1000 0001)

    @xxfelixxx得到了一些不同的东西,因为编码是作为显式标记执行的

    这两个字符串的标记是“1a”(VisibleString的通用标记)和“12”(NumericString的通用标记)

        2
  •  0
  •   xxfelixxx    6 年前

    我不知道你的十六进制字符串是从哪里来的。。。但是如果你使用 Convert::ASN1::encode 方法,则会得到一个稍微不同的十六进制字符串,可以正确解码:

    my $res = $asn->encode({ name => 'John Smith', phone => 9876543210 });
    my $res_hex = unpack 'H*', $res;
    print "res_hex after encode : $res_hex\n";
    print "original hex_data    : " . lc($hex_data) . "\n";
    print "\n";
    
    my payload = $asn1_node->decode($res) or die $asn1_node->error;
    use Data::Dumper;
    print Dumper($payload);
    

    输出

    res_hex after encode : 30181a0a4a6f686e20536d697468120a39383736353433323130
    original hex_data    : 3018800a4a6f686e20536d697468810a39383736353433323130
    
    $VAR1 = {
          'name' => 'John Smith',
          'phone' => '9876543210'
    };