【问题标题】:parsing asn.1 with bouncycastle用 bouncycastle 解析 asn.1
【发布时间】:2016-03-05 00:54:45
【问题描述】:

我有一些 asn.1 编码数据。我用 bouncycastle 解码它取得了一些成功,但我用相当复杂的例子碰壁了。一定是可行的,但不能更进一步,希望你能帮助我,这里是示例数据:

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);
    }

}

如您所见,我已经能够解码一些基本标签(即invokeID、操作值和crossRefIdentifier),但无法更深入地了解树(callId、callingNumber ...)。 如果您有这方面的经验,我将不胜感激。

【问题讨论】:

    标签: decode bouncycastle asn.1


    【解决方案1】:

    这是一个非常复杂的 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的转储在代码示例中添加了注释

    如果您有对象的 ASN.1 定义,您的生活会轻松很多。在Binary Notes 的帮助下,您可以生成类来解析 ASN.1 数据对象。

    【讨论】:

    • 感谢您的推荐。 BinaryNotes 为我生成了类。现在我只是在寻找有关如何使用它们的信息或示例。
    • 写在page 12的文档中
    • 谢谢,它看起来很有希望。不幸的是,更复杂的方法会导致异常(通常是空指针)。由于我正在尝试与 PBX 通信,因此我与 PBX 供应商进行了交谈,并正在寻找完整的 asn.1 包。看起来我已经找到的东西不能用于我的目的。我很好奇 BinaryNotes 是否会处理这些 asn.1 文件。使用 asn.1 文件,我找到了简单的方法 MonitorStart,生成了非常简单的输出: 03 03 00 33 32 ,这只是我应该收到的代码的一小部分。
    • 恐怕我无法进一步帮助您解决这个问题。我必须有权访问您拥有的所有东西(测试环境、PBX ...)。至于 BinaryNotes,我们已经对其进行了修改以使用充气城堡生成类(它看起来像我写的示例),所以也许调试和发现问题会更好。 BinaryNotes 将 ASN.1 表示法解析为 xml 结构,然后使用 xslt 转换生成代码类。默认情况下,它会生成自己的带有注释的类,但也许值得研究和更改以生成有弹性的类。
    • 我理解并感谢您的努力。也许当我从供应商那里收到 asn1 时,您可以尝试为我生成 bouncycastle 可解析类,仅用于 EventReport 一种方法。我的项目所需的不太复杂的结构我已经自己完成了,坦率地说,这个结构也几乎完成了。在某些时候,我在从 DERTaggedObject 读取二进制八位位组时遇到问题,但经过一些试验和错误并以不同的方式转换对象后,我终于读到了我想要的内容。我的课程不太像 OOP,但应该足以简单地读取从 PBX 接收到的事件。
    猜你喜欢
    • 2012-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多