用Objective-C的Security.framework库解析ASN.1数据

ASN.1 全称 Abstract Syntax Notation One,引用维基百科的介绍如下:

ASN.1本身只定义了表示信息的抽象句法,但是没有限定其编码的方法。各种ASN.1编码规则提供了由ASN.1描述其抽象句法的数据的值的传送语法(具体表达)。标准的ASN.1编码规则有基本编码规则(BER,Basic Encoding Rules)、规范编码规则(CER,Canonical Encoding Rules)、唯一编码规则(DER,Distinguished Encoding Rules)、压缩编码规则(PER,Packed Encoding Rules)和XML编码规则(XER,XML Encoding Rules)。

维基百科

ASN.1有BER、CER、DER、PER、XER,今天我们探索DER格式的数据解析,比如网站的HTTPS协议的证书(.cer扩展文件)就是DER编码的,我们也能看到.cer扩展并不一定就是CER编码。不过也有常规的用法,.crt.cer.key.csr大部分时候是DER编码,或者-----BEGIN…开头-----END...结尾的文本文件构成的PEM编码,也就是Privacy Enhanced Mail,其实PEM编码去掉开头,去掉结尾,然后base64解码,也是DER编码的。.p12大部分时候都是DER编码的。

为了学习DER编码数据的解码,我找到一个网站和一个StackOverFlow问题:

网站:

通过16进制编辑器保存StackOverFlow网站那个问题对应的数据到二进制文件, 也可以base64解码以下数据到文件:

MIGOMQswCQYDVQQGEwJJTDEPMA0GA1UECAwGaXNyYWVsMQwwCgYDVQQHDANUTFYxCzAJBgNVBAoMAlRTMR4wHAYDVQQLDBVDQV9jZXJ0aWZpY2F0ZV9zZXJ2ZXIxGzAZBgNVBAMMEmFhYWFhYWFNYWNCb29rX1BybzEWMBQGCSqGSIb3DQEJARYHekB6LmNvbQ==

使用openssl解析

openssl asn1parse -in sec.key -inform der

如下截图:

图片

使用asn1js直接解析16进制数据,如下截图:

图片

我们的目标是使用Security.framework提供的SecAsn1Decode来解析出如图的其他工具解析的内容,为了简单起见,仅解析每个SET->SEQUENCE 的值部分,SecAsn1Decode的原型如下:

OSStatus SecAsn1Decode(

需要coder、解码数据及其长度、ASN.1数据模板,目标存放payload。其中比较麻烦的地方在于构造解码SecAsn1Template,需要事先知道目标DER编码数据的结构(或者像我一样用其他工具先解码查看)。通过asn1js和openssl的结果我们可以知道结构是1个SEQUENCE包含7个SET,其中有SET都是包含1个SEQUENCE,SEQUENCE的内的数据有三种,都是1个oid,1个值。结构如下:

typedef struct

最终构造模板:

static const SecAsn1Template kATemplate[] =

最终解码代码如下:

SecAsn1CoderRef decoder = NULL;

执行结果:

图片

与其他工具解析结果相同(忽略了其他的结构信息),完整代码见我的github:

https://github.com/coleflowers/asn1decoder

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容