我有一个ASN.1数据,其中包含一些URL信息和证书数据。现在我正在尝试解析数据。我使用的转储方法如下所示。
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);
}
}
当我打印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?
?
现在如何解析上述数据以获取URL和证书数据等所需数据?
我们如何从上面的输出中识别URL和证书数据?有人可以帮忙吗?
答案 0 :(得分:1)
ASN.1编码对象仅包含结构化数据,但不包含每个字段的含义。需要ASN.1模块才能从对象中解码有意义的数据。该模块是一个数据规范,其目的是命名一组类型和(可选)值定义。
例如,这是X.509证书的ASN.1模块:http://tools.ietf.org/html/rfc5280#appendix-A.1
现在,假设您的ASN.1模块定义了此结构
MyData ::= SEQUENCE {
websiteURL UTF8String (SIZE (1..MAX)),
certificate Certificate,
}
您可以使用以下小代码段解码此对象:
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));
}
更新12月7日
根据您提供的ASN.1解码树,我认为证书包含在第二个Octet字符串对象中:
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
...
您需要从序列中获取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));
您还可以使用openssl ans1parse命令在ASN.1对象上打印更多详细信息