用OpenSSL解码ASN.1 DER八位字节字符串

用OpenSSL解码ASN.1 DER八位字节字符串,openssl,x509,asn.1,der,Openssl,X509,Asn.1,Der,使用OpenSSL API,我从X.509v3证书中提取了一个自定义扩展,它包含: X509_扩展*ex=X509_get_ext(X509,4); X509_扩展对象包含一个值(ex->value),该值是ASN.1八位字符串。八位字节字符串包含DER编码的UTF-8字符串。我正在尝试解码八位字节字符串以得到普通的UTF-8字符串 我尝试了一些方法,例如: ASN1\u字符串到UTF8(&buf,ex->value); 及 M_ASN1_OCTET_STRING_print(bio,ex-

使用OpenSSL API,我从X.509v3证书中提取了一个自定义扩展,它包含:

X509_扩展*ex=X509_get_ext(X509,4);
X509_扩展对象包含一个值(ex->value),该值是ASN.1八位字符串。八位字节字符串包含DER编码的UTF-8字符串。我正在尝试解码八位字节字符串以得到普通的UTF-8字符串

我尝试了一些方法,例如:

ASN1\u字符串到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字符串?

@Francois将我指向ASN1\u get\u 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”来实现这一点,遵循openssl代码中的示例(大约crypto/asn1/asn1_第c部分:135)。用这种方式解码一个大的结构是非常痛苦的,我建议使用另一个asn1解析器,如SNACC或libtasn1。@Francois:谢谢你的提示。因为我不想解码一个大的结构,只是一个字符串,ASN1_get_object()可能就足够了。然而,根据asn1_第c部分中如何使用它,我尝试过使用它,但无法让它工作。你能举个例子吗?@Francois:我发现了如何使用这个函数,并根据它发布了一个答案。再次感谢。我正试图做完全相同的事情,但当应用您的解决方案时,我得到的字符串与调用ASN1_get_对象函数之前的字符串相同。你确定这个函数可以解码吗?@Maggie:对于我正在处理的ASN.1类型,
octetstring
,它可以工作。但它可能是有效的,因为DER编码对
八位字节字符串所做的唯一事情就是用一个头将其包装起来。字节本身保持不变。ASN1_get_object()确实删除了头,但可能这就是它的全部功能?是的,ASN.1简单类型有
布尔型
整数型
位字符串
八位字符串
空值
对象标识符
实值
枚举的
字符串
。似乎您正在寻找一个关于如何提取x509v3扩展中信息的通用解决方案。正如这个问题的标题所述,它只是关于解码单个
八位字节字符串的特殊情况。除此之外,我只能向您指出@Francois的原始建议,即使用外部ASN.1解析器,如SNACC或libtasn1,并查看OpenSSL源代码(关于crypto/asn1/asn1_par.c:135)。@MrGomez:感谢链接。野马无法将我拖回OpenSSL API:)