2016-03-05 248 views
0

我有一些asn.1编码数据。我用bouncycastle解码它有一些成功,但是我用相当复杂的例子来打破墙壁。它必须是可行的,但不能得到进一步的,希望你能帮助我,这里是示例数据:用bouncycastle解析asn.1

A1 81 A9 02 02 1C 1F 02 01 15 30 81 9F 55 02 01 14 A0 81 98 A4 81 95 6B 10 30 0E 80 04 00 00 01 1F A1 06 30 04 80 02 33 32 63 06 30 04 80 02 33 32 61 0E 30 0C 80 0A 30 32 32 33 37 38 33 36 31 30 62 06 30 04 80 02 33 32 64 02 87 00 6B 13 30 11 80 04 00 00 01 1F A1 09 30 07 80 05 23 23 37 30 30 4E 01 02 0A 01 16 67 12 30 10 A3 0E 81 0C 2B 34 38 32 32 33 37 38 33 36 31 30 68 0F 30 0D A3 0B 82 09 32 32 38 36 35 33 33 39 38 65 09 30 07 80 05 23 23 37 30 30 7E 12 A0 10 18 0E 32 30 31 36 30 33 30 32 32 32 30 31 33 36 

CSTA Browser decoded: 

rOSE.roiv-apdu 
{ -- SEQUENCE -- 
    invokeID = 7199, 
    operation-value = 21 (cSTAEventReport), 
    argument 
    { -- SEQUENCE -- 
     crossRefIdentifier = '01 14'H, 
     eventSpecificInfo.callControlEvents.delivered 
     { -- SEQUENCE -- 
      connection.both 
      { -- SEQUENCE -- 
       callID = '00 00 01 1F'H, 
       deviceID.staticID 
       { -- SEQUENCE -- 
        deviceIdentifier.dialingNumber = "32" '33 32'H 
       } 
      }, 
      alertingDevice.deviceIdentifier 
      { -- SEQUENCE -- 
       deviceIdentifier.dialingNumber = "32" '33 32'H 
      }, 
      callingDevice.deviceIdentifier 
      { -- SEQUENCE -- 
       deviceIdentifier.dialingNumber = "0223783610" '30 32 32 33 37 38 33 36 31 30'H 
      }, 
      calledDevice.deviceIdentifier 
      { -- SEQUENCE -- 
       deviceIdentifier.dialingNumber = "32" '33 32'H 
      }, 
      lastRedirectionDevice.notKnown NULL, 
      originatingNIDConnection.both 
      { -- SEQUENCE -- 
       callID = '00 00 01 1F'H, 
       deviceID.staticID 
       { -- SEQUENCE -- 
        deviceIdentifier.dialingNumber = "##700" '23 23 37 30 30'H 
       } 
      }, 
      localConnectionInfo = 2 (alerting), 
      cause = 22 (newCall), 
      networkCallingDevice.deviceIdentifier 
      { -- SEQUENCE -- 
       deviceIdentifier.explicitPublic.international = "+48223783610" '2B 34 38 32 32 33 37 38 33 36 31 30'H 
      }, 
      networkCalledDevice.deviceIdentifier 
      { -- SEQUENCE -- 
       deviceIdentifier.explicitPublic.national = "228653398" '32 32 38 36 35 33 33 39 38'H 
      }, 
      associatedCallingDevice.deviceIdentifier 
      { -- SEQUENCE -- 
       deviceIdentifier.dialingNumber = "##700" '23 23 37 30 30'H 
      }, 
      extensions 
      { -- SEQUENCE -- 
       security 
       { -- SEQUENCE -- 
        timestamp = "20160302220136" '32 30 31 36 30 33 30 32 32 32 30 31 33 36'H 
       } 
      } 
     } 
    } 
} 

BouncyCastle的的垃圾产生类似的东西:

00 AC A1 81 A9 02 02 5F B9 02 01 15 30 81 9F 55 02 01 91 A0 81 98 A4 81 95 6B 10 30 0E 80 04 00 00 03 98 A1 06 30 04 80 02 33 32 63 06 30 04 80 02 33 32 61 0E 30 0C 80 0A 30 32 32 33 37 38 33 36 31 30 62 06 30 04 80 02 33 32 64 02 87 00 6B 13 30 11 80 04 00 00 03 98 A1 09 30 07 80 05 23 23 37 30 30 4E 01 02 0A 01 16 67 12 30 10 A3 0E 81 0C 2B 34 38 32 32 33 37 38 33 36 31 30 68 0F 30 0D A3 0B 82 09 32 32 38 36 35 33 33 39 38 65 09 30 07 80 05 23 23 37 30 30 7E 12 A0 10 18 0E 32 30 31 36 30 33 30 34 31 35 32 32 34 30 
buf:Tagged [1] IMPLICIT 
    Sequence 
     Integer(24505) 
     Integer(21) 
     DER Sequence 
      DER ApplicationSpecific[21] (0191) 
      Tagged [0] 
       Tagged [4] IMPLICIT 
        Sequence 
         DER ApplicationSpecific[11] 
          Sequence 
           Tagged [0] IMPLICIT 
            DER Octet String[4] 
           Tagged [1] 
            DER Sequence 
             Tagged [0] IMPLICIT 
              DER Octet String[2] 
         DER ApplicationSpecific[3] 
          Sequence 
           Tagged [0] IMPLICIT 
            DER Octet String[2] 
         DER ApplicationSpecific[1] 
          Sequence 
           Tagged [0] IMPLICIT 
            DER Octet String[10] 
         DER ApplicationSpecific[2] 
          Sequence 
           Tagged [0] IMPLICIT 
            DER Octet String[2] 
         DER ApplicationSpecific[4] 
          Tagged [7] IMPLICIT 
           DER Octet String[0] 
         DER ApplicationSpecific[11] 
          Sequence 
           Tagged [0] IMPLICIT 
            DER Octet String[4] 
           Tagged [1] 
            DER Sequence 
             Tagged [0] IMPLICIT 
              DER Octet String[5] 
         DER ApplicationSpecific[14] (02) 
         DER Enumerated(22) 
         DER ApplicationSpecific[7] 
          Sequence 
           Tagged [3] 
            Tagged [1] IMPLICIT 
             DER Octet String[12] 
         DER ApplicationSpecific[8] 
          Sequence 
           Tagged [3] 
            Tagged [2] IMPLICIT 
             DER Octet String[9] 
         DER ApplicationSpecific[5] 
          Sequence 
           Tagged [0] IMPLICIT 
            DER Octet String[5] 
         DER ApplicationSpecific[30] 
          Tagged [0] 
           GeneralizedTime(20160304152240GMT+01:00) 

,我想解析它:

protected void parse() { 
    logger.trace("Executing parse()"); 

    try { 

     ASN1InputStream input = new ASN1InputStream(asn1Data); 
     ASN1Primitive p; 

     if ((p = input.readObject()) != null) { 
      ASN1TaggedObject o1 = ASN1TaggedObject.getInstance(p); 
      ASN1Sequence s1 = ASN1Sequence.getInstance(o1.getObject()); 
      invokeID = Integer.parseInt(s1.getObjectAt(0).toString()); 
      operationValue = Integer.parseInt(s1.getObjectAt(1).toString()); 

      DERSequence ders = (DERSequence) DERSequence.getInstance(s1.getObjectAt(2)); 
      DERApplicationSpecific das = (DERApplicationSpecific) ders.getObjectAt(0); 
      crossRefIdentifier = das.getContents(); 



    //here are some experiments, but can't get the right objects I could parse/walk through 

      ASN1TaggedObject o2 = ASN1TaggedObject.getInstance(ders.getObjectAt(1)); 
      DERTaggedObject dto = (DERTaggedObject) o2.getObject(); 

      ASN1Sequence s2 = ASN1Sequence.getInstance(dto.getObject()); 
      DERApplicationSpecific das1 = (DERApplicationSpecific) s2.getObjectAt(0); 
      ASN1Sequence s3 = (ASN1Sequence) das1.getObject(); 

      } 
    } catch (Exception ex) { 
     logger.warn("exception while parsing ASN1 data", ex); 
    } 

} 

,你可以看到,我已经能够解码一些基本的标签(即调用ID,操作价值和crossRefIdentifier),但不能让树(呼叫标识,callingNumber更深.. )。 如果您有这方面的经验,我将非常感谢您的帮助。

回答

0

这是一个非常复杂的ASN.1对象。由于结构上的差异,有几个地方可能会出现另一个样本错误。这是一个例子。

using System; 
using System.Collections; 
using System.IO; 
using Org.BouncyCastle.Asn1; 

namespace Asn1ParseBouncy 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var bytes2Parse = File.ReadAllBytes(@"c:\a.req"); 

      // (0,169) CONTEXT SPECIFIC(1) 
      DerTaggedObject rootObj = (DerTaggedObject)Asn1Object.FromByteArray(bytes2Parse); 

      if (rootObj.TagNo == 1) 
      { 
       ParseAtRootLevel(rootObj); 
      } 
      else 
      { 
       throw new Exception("Expected Tag number to be 1"); 
      } 
     } 

     private static void ParseAtRootLevel(DerTaggedObject rootObj) 
     { 
      // SEQUENCE under CONTEXT SPECIFIC(1) 
      var seq = (Asn1Sequence)rootObj.GetObject(); 

      IEnumerator e = seq.GetEnumerator(); 
      bool hasNext; 
      hasNext = e.MoveNext(); 

      // (3,2) INTEGER -> invokeID 
      { 
       Asn1Encodable obj; 

       if (!hasNext) 
       { 
        throw new Exception("more entries expected in sequence"); 
       } 
       obj = (Asn1Encodable)e.Current; 

       // TODO: put in a property of class that represents whole ASN.1 message 
       var invokeID = DerInteger.GetInstance(obj); 

       hasNext = e.MoveNext(); 

      } 

      // (7,1) INTEGER -> operation-value 
      { 
       Asn1Encodable obj; 

       if (!hasNext) 
       { 
        throw new Exception("more entries expected in sequence"); 
       } 
       obj = (Asn1Encodable)e.Current; 

       // TODO: put in a property of class that represents whole ASN.1 message 
       var operationValue = DerInteger.GetInstance(obj); 

       hasNext = e.MoveNext(); 

      } 

      // (10,159) SEQUENCE -> argument 
      { 
       Asn1Encodable obj; 

       if (!hasNext) 
       { 
        throw new Exception("more entries expected in sequence"); 
       } 
       obj = (Asn1Encodable)e.Current; 

       var argumentSeq = Asn1Sequence.GetInstance(obj); 

       // argumentData is parsed asn.1 object - argument 
       var argumentData = ParseArgumentData(argumentSeq); 

       hasNext = e.MoveNext(); 
      } 

      if (hasNext) 
      { 
       throw new Exception("no more entries expected in sequence"); 
      } 
     } 

     private static object ParseArgumentData(Asn1Sequence argumentSeq) 
     { 
      IEnumerator e = argumentSeq.GetEnumerator(); 
      bool hasNext; 
      hasNext = e.MoveNext(); 

      // (13,2) APPLICATION (21) -> crossRefIdentifier 
      { 
       Asn1Encodable obj; 

       if (!hasNext) 
       { 
        throw new Exception("more entries expected in sequence"); 
       } 
       obj = (Asn1Encodable)e.Current; 

       var crossRefIdentifierAppSpecific = (DerApplicationSpecific)obj; 
       if (crossRefIdentifierAppSpecific.ApplicationTag != 21) 
        throw new Exception("Expected application tag 21"); 

       // TODO: put in a property of class that represents whole ASN.1 message 
       var crossRefIdentifier = crossRefIdentifierAppSpecific.GetContents(); 

       hasNext = e.MoveNext(); 

      } 

      // (17,152) CONTEXT SPECIFIC (0) -> eventSpecificInfo.callControlEvents.delivered 
      { 
       Asn1Encodable obj; 

       if (!hasNext) 
       { 
        throw new Exception("more entries expected in sequence"); 
       } 
       obj = (Asn1Encodable)e.Current; 

       var eventSpecificInfo = ((DerTaggedObject)obj); 

       if (eventSpecificInfo.TagNo != 0) 
        throw new Exception("Expected Context specific tag number to be 0"); 

       // TODO: put in a property of class that represents whole ASN.1 message 
       var eventSpecificInfoData = ParseEventSpecificInfo(eventSpecificInfo); 

       hasNext = e.MoveNext(); 

      } 

      if (hasNext) 
      { 
       throw new Exception("no more entries expected in sequence"); 
      } 

      // TODO: return parsed values in some class 
      return null; 
     } 

     private static object ParseEventSpecificInfo(DerTaggedObject obj) 
     { 
      // still (17,152) CONTEXT SPECIFIC (0) 
      var connectionBothData = ParseConnectionBoth(obj); 

      return connectionBothData; 
     } 

     private static object ParseConnectionBoth(DerTaggedObject connectionBoth) 
     { 
      // (20,149) CONTEXT SPECIFIC (4)->connection.both 
      var connectionBothTagged = (DerTaggedObject)connectionBoth.GetObject(); 

      if (connectionBothTagged.TagNo != 4) 
       throw new Exception("Expected Context specific tag number to be 4"); 

      // Sequence under (20,149) CONTEXT SPECIFIC (4) -> connection.both 
      var connectionBothSeq = (DerSequence)connectionBothTagged.GetObject(); 

      IEnumerator e = connectionBothSeq.GetEnumerator(); 
      bool hasNext; 
      hasNext = e.MoveNext(); 

      // callID 
      { 
       Asn1Encodable obj; 

       if (!hasNext) 
       { 
        throw new Exception("more entries expected in sequence"); 
       } 
       obj = (Asn1Encodable)e.Current; 

       // (23,16) APPLICATION (11) 
       // TODO: put in a property of class that represents whole ASN.1 message 
       var callIDTagged = (DerApplicationSpecific)obj; 
       if (callIDTagged.ApplicationTag != 11) 
        throw new Exception("Expected tag number 11"); 

       // (25,14) SEQUENCE 
       var callIdSeq = callIDTagged.GetObject().GetDerEncoded(); 

       // TODO: parse CallIdSeq -> (27,4) ContextSpecific(0), (33,6) ContextSpecific(1) 

       hasNext = e.MoveNext(); 

      } 

      // TODO: continue with (41,6) Application (3) 
      // TODO: continue with (49,14) Application (1) 
      // TODO: continue with (65,6) Application (2) 
      // etc. 

      // TOOD: return something useful 
      throw new NotImplementedException(); 
     } 
    } 
} 

我根据转储从ASN.1 Editor dump of your sample

你可以让你的生活变得更加简单,如果你有对象的ASN.1定义放置票据的代码样本。在Binary Notes的帮助下,您可以生成类来解析ASN.1数据对象。

+0

感谢您的建议。 BinaryNotes为我生成的类.. 现在我只是在寻找信息或如何使用它们的例子。 – norbi771

+0

它写在[第12页](http://bnotes.sourceforge.net/BinaryNotes.pdf) – pepo

+0

的文档谢谢,它看起来很有希望。不幸的是更复杂的方法会导致异常(通常为空指针)。由于我正在尝试与PBX通信,因此我与PBX供应商进行了交谈,并正在寻找完整的asn.1软件包。看起来我已经找到的东西不能用于我的目的。我很好奇,如果BinaryNotes会处理这些asn.1文件。 有了asn.1文件,我发现了简单的方法MonitorStart,生成了非常简单的输出:03 03 00 33 32,它只是我应该收到的代码的小子串。 – norbi771