parsing ASN files using bouncy castle

2019-08-24 00:25发布

问题:

am trying to parse binary CDRs using JASN1

I have successfully generated Java classes using grammer file not I have a CDR which I need to decode, but I can't get it to work, I don't understand what kind of inputs it requires

I have reached a point where I can parse CDR into lines like below

[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 code

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

download samples from here download grammer from here

回答1:

I was able to encode/decode the file with the help of JASN1 and BouncyCastle, I used JASN1 to compile grammer file into java classes then used BouncyCastle to decode/encode new objects, below is code snippet used to show how I did that

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


回答2:

Here is alternative way of processing given binary record files using org.bouncycastle.asn1 package only :

/*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());
                ...

            }

        }
    }

}