在证书上,主题AltName 中的电子邮件地址应为什么类型

2023-11-23

一点背景: 我正在建造一个证书颁发机构使用 M2Crypto 和 Django,所以请在投票之前三思而后行,将其视为题外话! :)

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

我见过many证书在野外的做法是将邮件地址存储为subjectAltName = rfc822:[email protected], but 谷歌搜索建议标准方法是subjectAltName = email:[email protected].

有没有any两者之间有区别,如果有的话,哪一个是首选?


两者之间有什么区别吗?如果有的话,首选哪一种?

并不真地;这取决于您使用的 PKI 配置文件。 PKI 和 X509 是狂野的、狂野的、西方的。

如果您在组织内部运行私有 PKI,那么如何操作并不重要。选择某件事并坚持不懈地去做。


在网络上通常是 PKIX 并在 RFC 5280 中指定,互联网 X.509 公钥基础设施证书和证书吊销列表 (CRL) 配置文件。根据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:[email protected] or email:[email protected]。就像我说的,这是狂野的西部。你应该为任何事情做好准备。


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

  • 基线证书要求
  • 扩展验证证书要求

但他们还是遵循 RFC 5280。


The rfc822: and 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 handy).

在上面,注意类型: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: or email:因为它遇到了一个类型GEN_EMAIL.


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

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

The email: is not逐字复制到 SAN 中。相反,它告诉 OpenSSL 使用GEN_EMAIL为该字段键入。


如果您的证书查看器或演示软件是not添加前缀,那么它可能会解析一个杰出的名字。

至于专有名称中的内容,Peter Gutmann 很久以前告诉我(摘自他的电子邮件):“在 DN 中粘贴您想要的任何内容,并仅显示有用的部分”。就像我说的,这是狂野的西部。


电子邮件地址也可能显示在 OID 下。例如,1.2.840.113549.1.9.1弧线。这是对 SAN 的补充。这就是为什么下图带有“电子邮件地址”标签的原因。


彼得·古特曼有一个X509 风格指南。取自他的描述:它描述了各种 X.509 证书实现细节和陷阱,提供了有关该做什么和不该做什么的建议,并以在现有实现中需要注意的已知错误和问题列表作为结束。


最后,这是Startcom颁发的用户证书。他们提供免费证书,并在需要时向您收取撤销费用(因为这就是成本所在)。这与其他 CA 完全相反,其他 CA 预先收取撤销费用,如果不需要则将其收入囊中;)

首先是X509证书:

enter image description here

第二个是使用 Gutmann 转储证书dumpasn1(从 www.cs.auckland.ac.nz/~pgut001 获取 dumpasn1.c 和 dumpasn1.cfg;使用以下命令进行编译gcc dumpasn1.c -o dumpasn1;并复制到/usr/local/bin)。注意没有rfc822: or email: prefix:

enter image description here

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在证书上,主题AltName 中的电子邮件地址应为什么类型 的相关文章

随机推荐

  • 通配符可按精确扩展名获取文件

    在诊断需要循环文件的较大批处理脚本时 log扩展我发现了一个有趣的行为 在包含如下文件的示例目录中 bar log foo log foo log ignore foo log log 1676521099 not related 我的小测
  • START TRANSACTION 在 BEGIN ... END 上下文中或在 and LOOP 语法之外

    我有两个关于 MySQL 中的复合语句和事务的问题 FIRST MySQL手册中有两处注释 Note 在所有存储的程序中 解析器将 BEGIN WORK 视为 BEGIN END 块的开头 在此开始交易 上下文 请使用 START TRAN
  • Android - 使用 JSOUP 解析 JS 生成的 url

    我试图解析由 Bootstrap s Bootpage js 生成的 url 它看起来像https example com page 2但 JSOUP 无法解析它并显示主 url 如何从 Bootpage 获取正常链接或如何使 JSOUP
  • 由于迁移到 java 1.7 Xml 文档元素不会缩进

    我正在尝试缩进由 Transformer 生成的 XML 除了第一个节点 文档元素之外 所有 DOM 节点都按预期缩进 文档元素不另起一行 只是在 XML 声明之后连接 当我迁移到 java 1 7 时 会出现此错误 而使用 java 1
  • 为什么 Java 中允许将 double 转换为 char?

    Why is char c char 65 8 Java 中允许吗 既然这样它不应该抛出错误吗65 8不是一个精确的 Unicode 值 我知道双精度数被截断为整数 在这种情况下 65 但对我来说允许程序员进行这样的转换似乎是糟糕的设计 它
  • 将 X 轴标签与图表列对齐(ASP.Net 图表控件)

    我正在尝试使用 ASP Net Chart 控件制作一个图表 该控件在 X 轴上具有特定的数值 在 Y 轴上具有频率计数 以下是我想要从要替换的图表框架中获得的内容的示例 在上面的示例中 X 轴标签与列对齐 但是 使用 ASP Net Ch
  • 单击 RecyclerView 列表项

    我有一个RecyclerView with a LinearLayoutManager and an Adapter Override public int getItemViewType int position return posit
  • jQuery - 将 .one() 与悬停一起使用

    有没有办法让悬停函数只执行一次 这就是我目前正在尝试的 ask live hover function homesearch after hide 300 doTimeout 300 function hideClosedSearchLin
  • @with 注释到底有什么作用? (播放框架)

    我不太明白 with注释的作用 在Play框架站点中 它是这样写的 我们可以使用 With注释来注释控制器来告诉 Play调用相应的拦截器 和继承一样吗 它会调用给定类参数的 before吗 它到底有什么作用 我描述它的最好方法是 它为您的
  • 是否可以阻止 Jetpack Compose 输入修饰符消耗输入事件?

    在旧的 Android View 范例中 视图可以侦听 MotionEvent 而不消耗它们 DispatchTouchEvent or OnTouchEvent可以简单地返回 false 并且 MotionEvent 将穿过一层又一层的视
  • 在树莓派 4 上安装 Rust 后无法运行货物

    我尝试使用推荐的安装脚本在 Raspberrypi 4 上安装 rust pi raspberrypi tmp curl https sh rustup rs sSf sh 但重启后 cargo找不到 pi raspberrypi carg
  • 如何在 post-receive hooks 中获取推送者的信息?

    Git 中的作者 提交者和推送者可以是不同的人 但 git 并没有在日志中存储推送者的信息 那么 我如何得到它 你不知道 The 上游回购不对谁提供提交做出任何假设 可以通过电子邮件 USB 密钥上复制的差异补丁以及其他方式各种传输协议 其
  • 如何使用加速度计计算步数?

    我必须开发与此相同的功能计步器应用程序 我观察到了这一点计步器应用程序非常详细 这不是一个完美的计步器应用程序 例如 如果您停留 坐在一个地方并握手 它还会检测步数和距离 忽略这种理想和重力行为 因为在这个应用程序的说明中已经提到你应该绑住
  • Angular2 与 Haml

    是否可以在 Angular 2 中使用 HAML 作为模板引擎 在 Angular 2 版本2 3 1 你可以使用 scss sass 代替 css 这是给定的选项angular cli with style 对于模板 cli 只允许通过设
  • Spring在没有@Autowired注解的构造函数中注入依赖项

    我正在尝试这个官方 Spring 的示例教程并且对这段代码有依赖 https github com spring guides gs async method tree master complete 如果你看一下代码AppRunner j
  • Rails:查找 HABTM 关系中没有连接的行

    我有两个模型 Users and Leads与HABTM关系相连 class Lead lt ActiveRecord Base has and belongs to many users end class User lt ActiveR
  • 在 Spring Security 中禁用浏览器身份验证对话框

    我正在使用 spring security 4 出于某种原因 在我使用登录页面完成身份验证后 我收到浏览器身份验证对话框 这迫使我再次进行身份验证 这是我的安全配置 http antMatcher test httpBasic and au
  • Google App Engine 自定义域未激活 Google 管理的 SSL

    我在 Google App Engine 上成功为我的应用程序配置了自定义域 我可以通过以下方式访问我的应用程序 http www myapp com 但是 在我的自定义域仪表板上 Google 管理的 SSL 需要很长时间才能激活 我有一
  • 一点到这条曲线的最短距离

    我需要找到多个点到以下形式的曲线的距离 f x a k bx 我的第一个选择是使用它的导数 使用导数的倒数形式的线 给出它的坐标Point并将其与原始曲线相交 最后 我们用简单的几何计算点之间的距离 这就是我通常遵循的数学过程 我需要节省时
  • 在证书上,主题AltName 中的电子邮件地址应为什么类型

    一点背景 我正在建造一个证书颁发机构使用 M2Crypto 和 Django 所以请在投票之前三思而后行 将其视为题外话 我的方法是 最终用户通过电子邮件地址进行识别 并且他们的自签名信任锚显然是由他们自己发布的 但我应该如何存储他们的 身