简体   繁体   English

java中如何使用bouncycastle解析ASN.1对象并获取数据

[英]How to parse the ASN.1 object and get the data using bouncycastle in java

I have an ASN.1 data which contain some URL info and certificates data.我有一个 ASN.1 数据,其中包含一些 URL 信息和证书数据。 Now I am trying to parse the data.现在我正在尝试解析数据。 I am using the dump method which is shown below.我正在使用如下所示的转储方法。

  private static void dump(ASN1Object obj, StringBuffer buf, int depth)  throws Exception
  {
    indent(buf, depth);
    if (obj == null)
    {
      buf.append("Null").append(NL);

    }
    else if (obj instanceof DERBitString)
    {
          try {

              DERBitString dbr =  (DERBitString)obj;
              Log.e("Testing", "DERBitString length:"+dbr.getBytes().length);

        } catch (Exception e) {
            // TODO: handle exception
            Log.e("Testing", "Exception :"+e);
        }

     // buf.append("DERBitString : ").append(((DERBitString)obj).getBytes().length * 8).append(" bits").append(NL);
      buf.append("DERBitString content111 : ").append(new String(((DERBitString)obj).getBytes())).append(NL);



      cert.write(obj.getEncoded());
    }
    else if (obj instanceof ASN1String)
    {
        Log.i("Testing", "Hashcode:"+obj.hashCode());
        buf.append("ASN1String : ").append(((ASN1String)obj).getString()).append(NL);
        if(numOctString == 1 && sURL == null )
        {
            sURL = ((ASN1String)obj).getString();
        }
        else
        {
            cert.write(obj.getEncoded());
        }
    }
    else if (obj instanceof ASN1UTCTime)
    {
      buf.append("ASN1UTCTime : ").append(((ASN1UTCTime)obj).getTime()).append(NL);
      cert.write(obj.getEncoded());
    }
    else if (obj instanceof ASN1GeneralizedTime)
    {
      buf.append("ASN1GeneralizedTime : ").append(((ASN1GeneralizedTime)obj).getTime()).append(NL);
      cert.write(obj.getEncoded());
    }
    else if (obj instanceof ASN1ObjectIdentifier)
    {
        buf.append("ASN1ObjectIdentifier : ").append((ASN1ObjectIdentifier)obj).append(NL);

        ASN1ObjectIdentifier identifier =  (ASN1ObjectIdentifier)obj;

        cert.write(obj.getEncoded());
        //buf.append("ASN1ObjectIdentifier : ").append(OidMap.get(((ASN1ObjectIdentifier)obj).getId())).append(NL); 
    }
    else if (obj instanceof ASN1Integer)
    {
      buf.append("ASN1Integer : ").append(((ASN1Integer)obj).getValue().toString()).append(NL);
      cert.write(obj.getEncoded());
    }
    else if (obj instanceof ASN1Boolean)
    {
      buf.append("ASN1Boolean : ").append(((ASN1Boolean)obj).isTrue() ? "true" : "false").append(NL);
      cert.write(obj.getEncoded());
    }
    else if (obj instanceof ASN1OctetString)
    {
       numOctString ++;
      buf.append("ASN1OctetString").append(NL);
      ASN1OctetString octObj = (ASN1OctetString)obj;
      try
      {
        ASN1InputStream aIn = new ASN1InputStream(octObj.getOctetStream());
        ASN1Primitive dobj = aIn.readObject();
        dump(dobj, buf, depth + 1);
      }
      catch(Exception e)
      {
        indent(buf, depth + 1);
        //buf.append(ByteArrayUtil.toHexString(octObj.getOctets(), ":")).append(NL);
      }
    }
    else if (obj instanceof ASN1TaggedObject)
    {
      buf.append("ASN1TaggedObject").append(NL);
      dump(((ASN1TaggedObject)obj).getObject(), buf, depth + 1);
    }
    else if (obj instanceof ASN1Sequence)
    {
      buf.append("ASN1Sequence").append(NL);

      Enumeration objs = ((ASN1Sequence)obj).getObjects();
      while (objs.hasMoreElements())
      {
        Object o = objs.nextElement();
        if (o == null || o instanceof DERNull)
        {
          indent(buf, depth + 1);
          //ASN1VectorImpl impl= new ASN1VectorImpl((ASN1Sequence)obj);
          buf.append("DERNull").append(NL);
        }
        else if (o instanceof ASN1Primitive)
        {
          dump((ASN1Primitive)o, buf, depth + 1);
        }
        else
        {
          dump(((ASN1Encodable)o).toASN1Primitive(), buf, depth + 1);
        }
      }
    }
    else if (obj instanceof ASN1Set)
    {
      buf.append("ASN1Set").append(NL);

      Enumeration objs = ((ASN1Set)obj).getObjects();
      while (objs.hasMoreElements())
      {
        Object o = objs.nextElement();
        if (o == null || o instanceof DERNull)
        {
          indent(buf, depth + 1);
          buf.append(NL);
        }
        else if (o instanceof ASN1Primitive)
        {
          dump((ASN1Primitive)o, buf, depth + 1);
        }
        else
        {
          dump(((ASN1Encodable)o).toASN1Primitive(), buf, depth + 1);
        }
      }
    }
    else
    {
        Log.e("Testing", "==================Else case=============");
        Log.e("Testing", "==================obj============="+obj.getEncoded().length);
      buf.append(obj.getClass().getName()).append(NL);
    }      
  }

When I print the StringBuffer i am getting the output as below.当我打印 StringBuffer 时,我得到如下输出。

 ASN1Sequence
   ASN1Sequence
     ASN1String : 1
     ASN1OctetString
       ASN1Sequence
         ASN1String : https://website url(Some StringDta )
         ASN1String : StringDta
         ASN1Sequence
           ASN1OctetString
             ASN1Sequence
               ASN1Sequence
                 ASN1TaggedObject
                   ASN1Integer : 2
                 ASN1Integer : 288799720653653968683086
                 ASN1Sequence
                   ASN1ObjectIdentifier : 1.2.840.113549.1.1.5
                   DERNull
                 ASN1Sequence
                   ASN1Set
                     ASN1Sequence
                       ASN1ObjectIdentifier : 2.5.4.3
                       ASN1String : StringDta
                 ASN1Sequence
                   ASN1UTCTime : 130417071944GMT+00:00
                   ASN1UTCTime : 140417072944GMT+00:00
                 ASN1Sequence
                   ASN1Set
                     ASN1Sequence
                       ASN1ObjectIdentifier : 2.5.4.10
                       ASN1String : StringDta
                   ASN1Set
                     ASN1Sequence
                       ASN1ObjectIdentifier : 2.5.4.3
                       ASN1String : StringDta
                   ASN1Set
                     ASN1Sequence
                       ASN1ObjectIdentifier : 1.2.840.113549.1.9.1
                       ASN1String : StringDta
                 ASN1Sequence
                   ASN1Sequence
                     ASN1ObjectIdentifier : 1.2.840.113549.1.1.1
                     DERNull
                   DERBitString content111 : 0?
 ?

Now how can parse the above data to get the required data like URL and certificates data?现在如何解析上述数据以获取所需的数据,如 URL 和证书数据?

How can we identify the URL and certificates data from above output?我们如何从上面的输出中识别 URL 和证书数据? Can some one help on this?有人可以帮忙吗?

The ASN.1 encoded object only contains the structured data but not the meaning of every field. ASN.1 编码对象只包含结构化数据,而不包含每个字段的含义。 An ASN.1 module is required in order to decode meaningful data from the object.需要一个 ASN.1 模块来解码来自对象的有意义的数据。 The module is a data specification, its purpose is to name a set of types and (optionally) values definitions.该模块是一个数据规范,其目的是命名一组类型和(可选)值定义。

For instance this is the ASN.1 module for X.509 certificates: http://tools.ietf.org/html/rfc5280#appendix-A.1例如,这是 X.509 证书的 ASN.1 模块: http : //tools.ietf.org/html/rfc5280#appendix-A.1

Now, assuming that your ASN.1 module defines this structure现在,假设你的 ASN.1 模块定义了这个结构

MyData ::= SEQUENCE {
    websiteURL         UTF8String (SIZE (1..MAX)),
    certificate        Certificate,
}

You can decode this object with this small code snippet:你可以用这个小代码片段解码这个对象:

public void decode(byte[] encoding) throws Exception
{
  ASN1Sequence seq = ASN1Sequence.getInstance(encoding);
  String url = DERUTF8String.getInstance(seq.getObjectAt(0)).getString();
  CertificateFactory factory = CertificateFactory.getInstance("X.509");
  byte[] certEnc = seq.getObjectAt(1).toASN1Primitive().getEncoded();
  Certificate cert = factory.generateCertificate(new ByteArrayInputStream(certEnc));
}

UPDATE Dec, 7th 12 月 7 日更新

According to the ASN.1 decoding tree you gave I think that the certificate is contained in the second Octet String Object:根据您提供的 ASN.1 解码树,我认为证书包含在第二个八位字节字符串对象中:

ASN1Sequence
  ASN1Sequence
    ASN1String : 1
    ASN1OctetString
      ASN1Sequence
        ASN1String : https://website url(Some StringDta )
        ASN1String : StringDta
        ASN1Sequence
          ASN1OctetString
            ASN1Sequence        <-- IMHO the certificate starts here
              ASN1Sequence
                ASN1TaggedObject
                  ASN1Integer : 2
                ASN1Integer : 288799720653653968683086
...

You need to get the ASN1OctetString object from the sequence, get the byte[] it wraps and decode the certificate.您需要从序列中获取ASN1OctetString对象,获取它包装的 byte[] 并解码证书。

ASN1Sequence seq = ...
ASN1OctetString ostr = ASN1OctetString.getInstance(seq.getObjectAt(0));
byte[] encodedCertificate = ostr.getOctets();
Certificate cert = CertificateFactory.getInstance("X.509").generateCertificate(new ByteArrayInputStream(encodedCertificate));

You can also use openssl ans1parse command to print more details on the ASN.1 objects您还可以使用 openssl ans1parse命令打印有关 ASN.1 对象的更多详细信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM