我是ASN1记号的新手,但我为无法继续进行而感到震惊。我能够使用ASN1Dump.dumpAsString()转储输出[引自link]

我可以转储(请参见下面的示例)。但我想提取单个值并使用它们。如何将其转换为类或访问单个oid?

Sequence
    DER Set
        Sequence
            ObjectIdentifier(1.3.6.1.4.1.4843.1.1)
            PrintableString(testValue1)
    DER Set
        Sequence
            ObjectIdentifier(1.3.6.1.4.1.4843.1.2)
            PrintableString(testValue2)
    DER Set
        Sequence
            ObjectIdentifier(1.3.6.1.4.1.4843.1.3)
            PrintableString(testValue3)


我想要这样的东西。

t.getValue("1.3.6.1.4.1.4843.1.1") should return testValue1 where t is of type some TestClass which contains members of testValue1,testValue2,testValue3.


提前致谢..

最佳答案

我假设,如果可以使用ASN1Dump,则您已经具有上面结构的对象。

对于此答案,我创建了相同的结构(因为我没有您的原始数据),但有细微的差别(DERSequence而不是Sequence),但是逻辑基本相同。

您需要解析asn1结构并存储所需的字段。对于此代码,我使用了bouncycastle 1.46 jdk1.6。

首先,使用解析器创建一个构造器来创建TestClass(与传递给ASN1Dump.dumpAsString()的对象相同。我假设它是一个DERSequence-可能是,但它也可以是一个ASN1Sequenceobj.getClass()以确保)。代码不会更改,因为ASN1SequenceDERSequence的超类,并且所使用的方法属于该超类。

public class TestClass {
    // this map will contain the values (key is 1.3.6.etc and value is testValue1, testValue2...)
    private Map<String, String> fields = new HashMap<String, String>();

    public TestClass(DERSequence sequence) {
        // parse objects from sequence
        Enumeration<?> objects = sequence.getObjects();
        while (objects.hasMoreElements()) {
            DERSet set = (DERSet) objects.nextElement(); // casting because I know from dump it's a DERSet

            // I'm assuming it's a DERSequence, but do a System.out.println(set.getObjectAt(0).getClass()) to make sure and cast accordinly
            DERSequence seq = (DERSequence) set.getObjectAt(0);

            // I'm assuming it's a DERObjectIdentifier, but do a System.out.println(set.getObjectAt(0).getClass()) to make sure and cast accordinly
            DERObjectIdentifier oid = (DERObjectIdentifier) seq.getObjectAt(0); // this object contains 1.3.6.etc...

            // I'm assuming it's a DERPrintableString, but do a System.out.println(set.getObjectAt(1).getClass()) to make sure and cast accordinly
            DERPrintableString str = (DERPrintableString) seq.getObjectAt(1);

            // store the values in the map
            fields.put(oid.getId(), str.getString());
        }
    }

    public String getValue(String oid) {
        // optional: you can check for null, or if oid exists (fields.contains(oid)), and return "" or null when it doesn't
        return fields.get(oid);
    }
}


之后,您可以使用TestClass这样:

// assuming seq is the object you passed to ASN1Dump.dumpAsString
// check if its type is DERSequence (do a seq.getClass() to check)
// if it's another type of sequence, change the TestClass code accordingly, as already explained above
TestClass t = new TestClass(seq);
System.out.println(t.getValue("1.3.6.1.4.1.4843.1.1")); // prints testValue1


PS:请注意,我只是按照ASN1Dump打印的结构进行了解析:


对象是包含3组的序列


每个集合仅包含一个元素,这是一个序列


每个序列包含2个元素:对象标识符和可打印的字符串




我已经仔细研究了所有元素,直到获得所需的元素为止。

07-26 06:04