使用充气城堡解析 ASN 文件

parsing ASN files using bouncy castle

我正在尝试使用 JASN1

解析二进制 CDR

我已经使用语法文件成功生成了 Java 类 不是我有需要解码的 CDR,但我无法让它工作,我不明白它需要什么样的输入

我已经可以将 CDR 解析为如下所示的行

[1][[0]#01, [1]#26fd, [3]#4131002400, [8]#14040020236233, [9]#21436500000041, [10]#196105000045ffffffffffff, [13]#13900049999957, [14]#21436549999961, [15]#05, [16]#05, [17]#116102999954ffffffffffff, [22]#00a2, [23]#0001, [37]#0010, [38]#03, [40]#0324, [46]#06, [47]#05, [54]#00580720111220, [85]#04f4]

Java代码

public class JASN1 {

        public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub

            ByteArrayInputStream bais = new ByteArrayInputStream(readContentIntoByteArray(new File("sample.asn")));

            ASN1InputStream ais = new ASN1InputStream(new FileInputStream(new File("sample.asn")));

            while (ais.available() > 0) {
                DERTaggedObject primitive = (DERTaggedObject) ais.readObject();

                 System.out.println(primitive.toASN1Object());

                String encoded = toHexadecimal(new String(primitive.getEncoded()));

                bais = new ByteArrayInputStream(encoded.getBytes());

                MobileSampleMsg mobileSampleMsg = new MobileSampleMsg();

                mobileSampleMsg.decode(bais, true);

                System.out.println("MobileSampleMsg = " + mobileSampleMsg);

            }
            ais.close();

            /*
             * System.out.println(bais); MobileSampleMsg personnelRecord_decoded =
             * new MobileSampleMsg(); personnelRecord_decoded.decode(bais, true);
             * 
             * System.out.println("");
             * System.out.println("PersonnelRecord.name.givenName = " +
             * personnelRecord_decoded);
             */

        }

        private static byte[] readContentIntoByteArray(File file) {
            FileInputStream fileInputStream = null;
            byte[] bFile = new byte[(int) file.length()];
            try {
                // convert file into array of bytes
                fileInputStream = new FileInputStream(file);
                fileInputStream.read(bFile);
                fileInputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return bFile;
        }

        public static String toHexadecimal(String text) throws UnsupportedEncodingException {
            byte[] myBytes = text.getBytes("UTF-8");

            return DatatypeConverter.printHexBinary(myBytes);
        }
    }

here 下载样本 从 here

下载语法

我能够在 JASN1 和 BouncyCastle 的帮助下 encode/decode 文件,我使用 JASN1 将语法文件编译成 java 类 然后使用 BouncyCastle decode/encode 新对象,下面是用于展示我是如何做到的代码片段

public class BouncyCastle {

    public static void main(String[] args) throws IOException {

        DetailOutputRecord detailOutputRecord = new DetailOutputRecord();
        MyRecord myRecord = new MyRecord();

        myRecord.setOriginNodeType(new NodeType("xxxx".getBytes()));
        myRecord.setTransactionAmount(new MoneyAmount("xxxx".getBytes()));
        myRecord.setSubscriberNumber(new NumberString("xxxx".getBytes()));

        ReverseByteArrayOutputStream ros = new ReverseByteArrayOutputStream(1000);

        detailOutputRecord.setMyRecord(myRecord);
        myRecord.encode(ros);
        System.out.println(DatatypeConverter.printHexBinary(ros.getArray()));
        System.out.println(print(ros.getArray()));

        DERTaggedObject dermyRecord = new DERTaggedObject(false, 6, ASN1Primitive.fromByteArray(ros.getArray()));


        File f = new File(String.valueOf("1_dermyRecord.ASN"));
        FileOutputStream stream = new FileOutputStream(f);
        try {
            stream.write(dermyRecord.getEncoded());
        } finally {
            stream.close();
        }

        ros = new ReverseByteArrayOutputStream(1000);
        detailOutputRecord.encode(ros);

        DLSequence ddetailOutputRecord = new DLSequence(ASN1Primitive.fromByteArray(ros.getArray()));
        stream = new FileOutputStream(new File("detailOutputRecord.ASN"));
        try {
            stream.write(ros.buffer);
        } finally {
            stream.close();
        }



    }

    public static String print(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        sb.append("[ ");
        for (byte b : bytes) {
            // sb.append(String.format("0x%02X ", b));
            sb.append(String.format("\x%02X", b));
        }
        sb.append("]");
        return sb.toString();
    }

    private static DERTaggedObject toDERObject(byte[] data) throws IOException {
        ByteArrayInputStream inStream = new ByteArrayInputStream(data);
        ASN1InputStream asnInputStream = new ASN1InputStream(inStream);

        return (DERTaggedObject) asnInputStream.readObject();
    }
}

这是仅使用 org.bouncycastle.asn1 包处理给定二进制记录文件的替代方法:

/*Sequence Tags */
static final int MSCRecordType = 0;
static final int RecordNumber = 1;
static final int RecordStatus = 3;
static final int CallingImsi = 8;
static final int CallingImei = 9;


void process() throws IOException, ClassNotFoundException {
    String path = System.getProperty("user.dir") + "/telconetqual_sampledata/CDR_RGN0_20121120081859.asn";

    File file = new File(path);
    byte[] bFile = new byte[(int) file.length()];
    FileInputStream fis = new FileInputStream(file);
    fis.read(bFile);

    ASN1InputStream in = new ASN1InputStream(bFile);

    while (in.available() > 0) {
        ASN1Primitive primitive = in.readObject();
        DERTaggedObject derTaggedObject = (DERTaggedObject) primitive;
        DLSequence sequence = (DLSequence)derTaggedObject.getObject();
        for(int i =0; i < sequence.size(); i++){
            DERTaggedObject seqElement = (DERTaggedObject)sequence.getObjectAt(i);
            switch (seqElement.getTagNo()) {
                case MSCRecordType:
                    DEROctetString recordTypeOctet =(DEROctetString)seqElement.getObject();
                    int recordType = Integer.valueOf(Hex.toHexString(recordTypeOctet.getOctets()));
                    break;
                case CallingImsi:
                    DEROctetString  CallingImsiOctet =(DEROctetString)seqElement.getObject();
                    String CallingImsi = Hex.toHexString(CallingImsiOctet.getOctets());
                ...

            }

        }
    }

}