X.509 证书中的可分辨名称长度约束

Distinguished Name length constraint in X.509 certificate

DN of a X509 certificate 的通用名称字段中,如 OID“2.5.4.3”的 ASN.1 表示法中所定义,限制最多为 64 个字符。如果我们想要一个超过 64 个字符的通用名称,是否有任何转机?

即使您可以哄骗您的证书生成代码具有更长的 CN,客户端 也需要更改,其中大部分是您无法控制的。客户很可能会拒绝 CN 太长的证书,然后您将根本没有证书。

如评论中所述,您可以(并且应该)将该域名和其他域名放入主题别名扩展中,并将 CN 留空。不是全部 "Subject",只是其中的 CN 部分。

如果您想 "cajole" 像@Chris Cogdon 提到的证书生成代码,这并不难。作为逆向工程挑战的一部分,我需要这样做,因此它违反标准这一事实并不重要。我完全同意你不应该这样做的消息,但我仍然会解释我是如何做到的,因为我花了一点时间才弄明白。

以下是(粗略的)步骤:

  1. https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/ 下载 libressl 的最新源代码(我使用的是 2.6.0,因为它是 macOS Mojave 上附带的版本)
  2. Unzip/tar/gz 然后在您喜欢的编辑器中打开 /crypto/asn1/a_mbstr.c
  3. 搜索如下内容:
    if ((maxsize > 0) && (nchar > maxsize)) {
        ASN1error(ASN1_R_STRING_TOO_LONG);
        ERR_asprintf_error_data("maxsize=%ld", maxsize);
        return -1;
    }

并注释掉。对于 2.6.0 版,这是第 155-159 行。通过删除这些行,您将删除最大 CN 长度检查。

  1. 按照 README 文件中的说明构建二进制文件。当我在 macOS 上构建时,我不需要安装任何库,但 YMMV。我使用 cmake 将新的 openssl 二进制文件放入 /build/apps/openssl

  2. 使用命令行标志生成一个 CSR(阅读:不是交互式工具——它有一个特殊的检查,这个修改没有修补!)。

例如:

/build/apps/openssl/openssl req -new -newkey rsa:2048 -nodes -out a.csr -keyout a.key -subj "/CN=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"

  1. 使用现有 openssl 二进制文件(或修改后的二进制文件,如果需要),签署 CSR:openssl x509 -req -in a.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out a.crt -days 500 -sha256

之后,您应该准备好可以使用的精彩的不合规证书。正如评论中的许多人和 Chris Cogdon 所指出的那样,使用 CN 长度超过 64 个字符的证书存在很多问题(macOS curl 无法与使用这些证书的服务器对话,Wireshark 在解析器中截断 CN显示等)。然而,这个证书确实可以满足我的需要,所以我至少可以确认这些证书在某些特定情况下是有效的。

我在野外看到的一个技巧是使用通配符证书。

例如,CN = '*.example.com' 的证书可保护 'very-truly-tremendously-[...]-long-hostname.example.com'.