Bouncy Castle ASN1 从 BERTaggedObject 检索对象
Bouncy Castle ASN1 retrieving objects from BERTaggedObject
我正在使用 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
}
我能够从输入文件中成功读取对象。在 BERTaggedObject
berObj
上调用 toString
方法给出:
[20][[0]#12, [3]#12191031148270f3, [4]#5302816004686062,]
可以看到SGSNPDPRecord
的tag [20]
,[0]#12
是recordType和它的内容,这里一切都很好我用ASN1 Dump Utility检查了一下。
我坚持提取 SGSNPDPRecord
成员字段(recordType
、networkInititation
等)。
我不确定如何从 BERTaggedObject
berObj
.
中提取字段及其 berTag
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;
}
}
我正在使用 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()
得到对应的值,并根据每个字段的定义来处理这个值。
我正在使用 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
}
我能够从输入文件中成功读取对象。在 BERTaggedObject
berObj
上调用 toString
方法给出:
[20][[0]#12, [3]#12191031148270f3, [4]#5302816004686062,]
可以看到SGSNPDPRecord
的tag [20]
,[0]#12
是recordType和它的内容,这里一切都很好我用ASN1 Dump Utility检查了一下。
我坚持提取 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;
}
}
我正在使用 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()
得到对应的值,并根据每个字段的定义来处理这个值。