我正在使用Bouncy Castle来解码BER X.690 ASN.1文件。
以下是ASN.1映射文件的一部分:
CallEventRecord ::= CHOICE
{
sgsnPDPRecord [20] SGSNPDPRecord,
}
SGSNPDPRecord ::= SET
{
recordType [0] CallEventRecordType,
networkInitiation [1] NetworkInitiatedPDPContext OPTIONAL,
servedIMSI [3] IMSI,
servedIMEI [4] IMEI OPTIONAL
}
我能够从输入文件中成功读取对象。在toString
BERTaggedObject
上调用berObj
方法会给出:
[20] [[0]#12,[3]#12191031148270f3,[4]#5302816004686062,]
您可以看到SGSNPDPRecord
的标记[20]
,[0]#12
是recordType及其内容,所有内容都已完成,我使用ASN1转储实用程序进行了检查。
我很难提取SGSNPDPRecord
个成员字段(recordType
,networkInititation
等)。
我不确定如何从BERTaggedObject
berObj
中提取字段及其标记。
public class SGSNPDPRecord extends ASN1Object
{
Integer recordType;
Boolean networkInitiation;
String servedIMSI;
String servedIMEI;
private static int SGSNPDP_RECORD_BER_TAG = 20;
public SGSNPDPRecord(BERTaggedObject berObj) throws IOException {
int tagNo = berObj.getTagNo();
// Returns tag number 20, this one is OK
if (tagNo != SGSNPDP_RECORD_BER_TAG )
{
System.out.println("Invalid Tag Number!");
return;
}
// How to get here someObject that will check BER Tags of primitive fields recordType, networkInitiation ... and read content from the specific ber tag
switch ( someObj.getApplicationTag() )
{
case 0:
this.recordType = new Integer( someObj.getContents()[0] );
break;
case 1:
this.networkInitiation = new Boolean(new String( someObj.getContents()[0], "UTF-8"));
break;
case 3:
this.servedIMSI = new String(someObj.getContents(), "UTF-8");
break;
case 4:
this.servedIMEI = new String(someObj.getContents(), "UTF-8");
break;
default:
break;
}
}
@Override
public ASN1Primitive toASN1Primitive()
{
return null;
}
}
答案 0 :(得分:0)
我正在使用BouncyCastle 1.56。如果您使用的版本< = 1.46,则代码可能不同,因为版本1.47中有lots of significant changes in the API。
首先,我获得了您在评论中提供的数据,并构建了与CallEventRecord
对应的标记对象:
String s = "B480800112830812191031925895F0840853344080218389200000";
ASN1InputStream in = new ASN1InputStream(Hex.decode(s));
BERTaggedObject callEventRecord = (BERTaggedObject) in.readObject();
in.close();
我只是打印了标签和内容,只是为了确保它与您的相同:
System.out.println(callEventRecord.getTagNo()); // 20
System.out.println(callEventRecord.getObject()); // [[0]#12, [3]#12191031925895f0, [4]#5334408021838920]
输出:
20
[[0]#12,[3]#12191031925895f0,[4]#5334408021838920]
因此,标签是正确的(20),并且内容匹配相同的结构。让我们继续前进。
我刚检查了callEventRecord.getObject().getClass()
的值,它是org.bouncycastle.asn1.BERSequence
,它(根据上面的ASN.1定义)对应SGSNPDPRecord
。然后我浏览了它的元素,只是为了检查它们的类型:
// get the SGSNPDPRecord
BERSequence sgsnPDPRecord = (BERSequence) callEventRecord.getObject();
for (int i = 0; i < sgsnPDPRecord.size(); i++) {
System.out.println(sgsnPDPRecord.getObjectAt(i).getClass());
}
结果是3个元素,都是org.bouncycastle.asn1.DERTaggedObject
类型。然后我修改了循环以检查每个循环的内容:
for (int i = 0; i < sgsnPDPRecord.size(); i++) {
DERTaggedObject obj = (DERTaggedObject) sgsnPDPRecord.getObjectAt(i);
// get the value with obj.getObject()
switch (obj.getTagNo()) {
case 0: // CallEventRecordType
break;
case 1: // NetworkInitiatedPDPContext
break;
case 3: // IMSI
break;
case 4: // IMEI
break;
default:
break;
}
}
在循环内部,您只需调用obj.getObject()
即可获取每个标记的相应值。在我的测试中,所有元素都是org.bouncycastle.asn1.DEROctetString
的实例,但只有上面的ASN.1定义,我才能告诉每个字段应该如何处理。
因此,您应该使用obj.getObject()
获取相应的值,并根据每个字段的定义处理此值。