使用 OpenSSL 解码 ASN.1 DER OCTET STRING
Posted
技术标签:
【中文标题】使用 OpenSSL 解码 ASN.1 DER OCTET STRING【英文标题】:Decoding an ASN.1 DER OCTET STRING with OpenSSL 【发布时间】:2011-11-11 20:44:57 【问题描述】:使用 OpenSSL API,我从 X.509v3 证书中提取了一个自定义扩展:
X509_EXTENSION* ex = X509_get_ext(x509, 4);
X509_EXTENSION 对象包含一个 ASN.1 OCTET STRING 值(ex->value)。 OCTET STRING 包含一个 DER 编码的 UTF-8 字符串。我正在尝试解码 OCTET STRING 以获得纯 UTF-8 字符串。
我尝试了一些方法,例如:
ASN1_STRING_to_UTF8(&buf, ex->value);
和
M_ASN1_OCTET_STRING_print(bio, ex->value);
int len = BIO_read(bio, buf, buf_size);
buf[len] = '\0';
这些都给了我 DER 编码的字符串。如何获取纯 UTF-8 字符串?
【问题讨论】:
我之前使用 'asn1_get_object' 来执行此操作,遵循 openssl 代码中的示例(围绕 crypto/asn1/asn1_par.c:135)。以这种方式解码大型结构非常痛苦,我建议使用备用 asn1 解析器,例如 SNACC 或 libtasn1。 @Francois:谢谢你的提示。由于我没有尝试解码大型结构,因此只需一个字符串, ASN1_get_object() 可能就足够了。但是,我尝试使用它,基于它在 asn1_par.c 中的使用方式,但无法使其正常工作。能举个例子吗? @Francois:我发现了如何使用该功能并基于此发布了答案。再次感谢。 【参考方案1】:@Francois 向我指出了 ASN1_get_object() 函数。该函数适用于证书扩展仅包含单个值的情况。
ASN1_get_object() 将指针指向包含 DER 编码对象的 C 缓冲区的指针。它返回数据本身(通过调整指针)、数据长度、ASN.1标签值和ASN.1对象类。
ASN1_OCTET_STRING* octet_str = X509_EXTENSION_get_data(extension);
const unsigned char* octet_str_data = octet_str->data;
long xlen;
int tag, xclass;
int ret = ASN1_get_object(&octet_str_data, &xlen, &tag, &xclass, octet_str->length);
printf("value: %s\n", octet_str_data);
【讨论】:
我试图做完全相同的事情,但是在应用您的解决方案时,我得到与调用 ASN1_get_object 函数之前相同的字符串。你确定这个函数可以解码吗? @Maggie:对于我正在处理的 ASN.1 类型OCTET STRING
,它可以工作。但它可能是有效的,因为 DER 编码对OCTET STRING
所做的唯一事情就是用标头包装它。字节本身保持不变。 ASN1_get_object() 确实删除了标题,但也许这就是 all 它所做的?
是的,ASN.1 简单类型是BOOLEAN
、INTEGER
、BIT STRING
、OCTET STRING
、NULL
、OBJECT IDENTIFIER
、REAL
、ENUMERATED
和 @ 987654332@.
您似乎正在寻找有关如何在 x509v3 扩展中提取信息的通用解决方案。正如这个问题的标题所述,它只是关于解码单个OCTET STRING
的特殊情况。除此之外,我只能向您指出@Francois 的原始建议,即使用外部 ASN.1 解析器,例如 SNACC 或 libtasn1,并查看 OpenSSL 源代码(围绕 crypto/asn1/asn1_par.c: 135). 跨度>
@MrGomez:感谢您的链接。野马无法将我拖回 OpenSSL API :)以上是关于使用 OpenSSL 解码 ASN.1 DER OCTET STRING的主要内容,如果未能解决你的问题,请参考以下文章