我有一些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,operation-value和crossRefIdentifier),但不能在树中更深入(callId,callingNumber ...)。 如果您有相关经验,我将非常感谢您的帮助。
答案 0 :(得分: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的转储在代码示例中放置了注释
如果你有对象的ASN.1定义,你可以让你的生活更轻松。在Binary Notes的帮助下,您可以生成用于解析ASN.1数据对象的类。