2016-03-05 251 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