在证书上,在subjectAltName中应该是电子邮件地址的类型

时间:2013-06-18 14:58:56

标签: openssl x509 m2crypto

一点背景: 我正在使用M2Crypto和Django构建一个certificate authority,所以请在投票之前三思而后行以关闭主题! :)

我的方法是通过电子邮件地址识别最终用户,并且他们自己签署的信任锚明显地由他们自己发布,但我应该如何存储他们的“身份”?

我在野外看到了许多证书,其中的做法是将邮件地址存储为subjectAltName = rfc822:user@domain.test,但标准方式为googling suggest { {1}}。

两者之间是否存在任何差异,如果是,那么首选哪一个?

1 个答案:

答案 0 :(得分:4)

  

这两者之间是否存在差异?如果是,那么首选哪一个?

不是真的;这取决于您使用的PKI配置文件。 PKI和X509是狂野的野生西部。

如果您在组织内部运行私有PKI,则无论如何操作都无关紧要。选择一些东西并持续做。


在网络上它通常是PKIX并在RFC 5280中指定Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile。根据4.1.2.6,主题:

Conforming implementations generating new certificates with
electronic mail addresses MUST use the rfc822Name in the subject
alternative name extension (Section 4.2.1.6) to describe such
identities.  Simultaneous inclusion of the emailAddress attribute in
the subject distinguished name to support legacy implementations is
deprecated but permitted.

然后第4.2.1.6节,主题替代名称:

When the subjectAltName extension contains an Internet mail address,
the address MUST be stored in the rfc822Name.  The format of an
rfc822Name is a "Mailbox" as defined in Section 4.1.2 of [RFC2821].
A Mailbox has the form "Local-part@Domain".  Note that a Mailbox has
no phrase (such as a common name) before it, has no comment (text
surrounded in parentheses) after it, and is not surrounded by "<" and
">".

请注意,它不使用rfc822:user@domain.testemail:user@domain.test。就像我说的那样,狂野的西部。你应该做好准备。


您还拥有CA /浏览器论坛及其颁发证书的标准。感兴趣的两个文件是:

但是他们推迟回到RFC 5280。


您看到的rfc822:email:可能是由软件添加进行演示。例如,要使用OpenSSL枚举SAN,您的功能类似于:

void print_san_name(X509* const cert)
{
    int success = 0;
    GENERAL_NAMES* names = NULL;
    unsigned char* utf8 = NULL;

    do
    {
        if(!cert) break; /* failed */

        names = X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0 );
        if(!names) break;

        int i = 0, count = sk_GENERAL_NAME_num(names);
        if(!count) break; /* failed */

        for( i = 0; i < count; ++i )
        {
            GENERAL_NAME* entry = sk_GENERAL_NAME_value(names, i);
            if(!entry) continue;

            if(GEN_DNS == entry->type)
            {
                int len1 = 0, len2 = -1;

                len1 = ASN1_STRING_to_UTF8(&utf8, entry->d.dNSName);
                if(utf8) {
                    len2 = (int)strlen((const char*)utf8);
                }

                if(len1 != len2) {
                    fprintf(stderr, "Strlen and ASN1_STRING size do not match (embedded null?):"
                                    " %d vs %d\n", len2, len1);
                    /* Handle error */
                }

                /* Do something with utf8 */

                if(utf8) {
                    OPENSSL_free(utf8), utf8 = NULL;
                }
            }
            else if(GEN_EMAIL == entry->type)
            {
                ...
            }
            ...
        }

    } while (0);

    if(names)
        GENERAL_NAMES_free(names);

    if(utf8)
        OPENSSL_free(utf8);
}

(抱歉,我没有一个提取IA5Strings方便的例子。

在上面,请注意类型:GEN_DNS或一般DNS名称。这用于www.example.com之类的名称。 OpenSSL有几种类型,下面是x509v3.h

#define GEN_OTHERNAME   0
#define GEN_EMAIL       1
#define GEN_DNS         2
#define GEN_X400        3
#define GEN_DIRNAME     4
#define GEN_EDIPARTY    5
#define GEN_URI         6
#define GEN_IPADD       7
#define GEN_RID         8

您的证书查看器或演示文稿软件可能会显示rfc822:email:,因为它遇到类型GEN_EMAIL


当您查看OpenSSL的配置文件时,您将看到,例如:

...
[ v3_ca ]
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid:always,issuer:always
subjectAltName         = email:myEmail@email.com
issuerAltName          = issuer:copy

email: 逐字复制到SAN中。相反,它告诉OpenSSL对该字段使用GEN_EMAIL类型。


如果您的证书查看器或演示文稿软件添加前缀,那么它可能正在解析一个名为Distinguished。

至于名字中的名字,Peter Gutmann很久以前告诉过我(从他的电子邮件中提取):&#34;在DN中粘贴你想要的任何东西,只显示有用的部分&# 34 ;.就像我说的,它是野性的,狂野的西部。


电子邮件地址也可能出现在OID下。例如,1.2.840.113549.1.9.1 arc。除了SAN之外,还有这个。这就是为什么下面的图片有这个标签&#34;电子邮件地址&#34;。


彼得古特曼有X509 Style Guide。摘自他的描述:它描述了各种X.509证书实现细节和陷阱,提供了有关做什么和不做什么的建议,并完成了现有实现中需要注意的已知错误和问题列表。


最后,这是由Startcom发布的用户证书。他们提供免费证书,并在需要时向您收取撤销费用(因为这是成本所在的地方)。这与其他CA先生截然相反,如果不需要,他们可以预先收取撤销费用并将其收入囊中;)

第一个是X509证书:

enter image description here

第二个是使用Gutmann的dumpasn1转储证书(从www.cs.auckland.ac.nz/~pgut001获取dumpasn1.c和dumpasn1.cfg;使用{{1编译) }并复制到gcc dumpasn1.c -o dumpasn1)。请注意,没有/usr/local/binrfc822:前缀:

enter image description here