证书/CRL目录的哈希算法

leg*_*cia 1 openssl

OpenSSL 能够使用 CA 证书和 CRL 的特定目录结构。如果您将目录名称作为第三个参数传递给SSL_CTX_load_verify_locations(如本问题中所述),它将在此目录中查找 CA 证书以验证客户端证书。它通过获取客户端证书颁发者的哈希值并附加一个整数(例如 )来找到正确的 CA 证书34bb8598.0。通常,这些名称是指向真实文件的符号链接,并且符号链接是使用该c_rehash工具创建的。

同样,OpenSSL 可以将证书吊销列表存储在此类目录中,如本问题中所述,并通过证书颁发者的哈希值查找正确的吊销列表。

现在,我需要让程序重用这样的 CRL 目录。该程序不使用 OpenSSL,因此我需要以其他方式生成这些哈希值。生成这些散列文件名的算法是什么?

leg*_*cia 5

哈希格式没有记录,因此这可能会更改 \xe2\x80\x94 事实上,它已经更改过一次。该x509命令支持选项-subject_hash-issuer_hash以及-subject_hash_old-issuer_hash_old。此描述适用于 OpenSSL 1.0.1f 中的“新”哈希格式。

\n

X509_subject_name_hash函数X509_issuer_name_hash仅调用相应X509_NAME_hash证书属性。 该函数采用名称的“规范编码”的 SHA-1 哈希值,将其前四个字节视为小端 32 位整数,然后返回它(有效地反转哈希值的前四个字节)。

\n

那么什么是“规范编码”呢?它是发行人名称的 DER 表示形式的突变,由函数 生成x509_name_canon。DER 是一种标签长度值编码。我们表示的对象树如下所示:

\n
    \n
  • rdnSequence,带标记0x31(十进制 49)\n
      \n
    • 一个或多个RelativeDistinguishedName 项,每个项都带有标记0x30(十进制 48)\n
        \n
      • 一种类型,表示为 OID,带有标签0x06
      • \n
      • 字符串值 \xe2\x80\x94 这就是它变得有趣的地方
      • \n
      \n
    • \n
    \n
  • \n
\n

证书中给出的字符串值可以用多种不同类型表示,例如带有 tag 的“可打印字符串” 0x13、带有 tag 的“IA5 字符串”0x16或带有 tag 的 UTF-8 字符串0x0c

\n

生成“规范编码”时,RDNSequence 中每个项目的值都会转换为 UTF-8,并使用标签重新编码为 UTF-8 字符串0x0c。这发生在asn1_string_canon函数中。此外,还应用了以下转换:

\n
    \n
  • 任何前导和尾随空格都将被删除。任何设置了高位位的字节都会不做任何更改地通过,因此在此上下文中的“空白”意味着空格、换页、换行符、回车、水平制表符和垂直制表符。
  • \n
  • 在字符串内部,任何一个或多个如上定义的空白字符都会被替换为一个空格 ( 0x20)。
  • \n
  • 字符被转换为小写。由于任何具有高位设置的字节都会被忽略,因此这只适用于 ASCII 字母 A 到 Z。
  • \n
\n

这就是您需要做的全部。

\n

请注意,某些相关字段的 ASN.1 定义不允许使用 UTF-8 字符串(例如,国家/地区代码仅限于“可打印字符串”),因此您可能无法使用 ASN.1 编码库直接地。

\n