证书/CRL目录的哈希算法

问题描述 投票:0回答:1

OpenSSL 能够使用 CA 证书和 CRL 的特定目录结构。如果您将目录名称作为第三个参数传递给

SSL_CTX_load_verify_locations
(如这个问题中所述),它将在此目录中查找 CA 证书以验证客户端证书。它通过获取客户端证书颁发者的哈希值并附加一个整数来找到正确的 CA 证书,例如
34bb8598.0
。通常,这些名称是指向真实文件的符号链接,并且符号链接是使用
c_rehash
工具创建的。

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

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

openssl
1个回答
5
投票

哈希格式没有记录,所以这可能会改变——事实上,它已经改变过一次。

x509
命令支持选项
-subject_hash
-issuer_hash
以及
-subject_hash_old
-issuer_hash_old
。此描述适用于 OpenSSL 1.0.1f 中的“新”哈希格式。

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

那么什么是“规范编码”?它是发行人名称的 DER 表示形式的突变,由函数

x509_name_canon
生成。 DER 是一种标签长度值编码。我们代表的对象树如下所示:

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

证书中给出的字符串值可以用多种不同类型表示,例如带有标签

0x13
的“可打印字符串”、带有标签
0x16
的“IA5 字符串”或带有标签
0x0c
的 UTF-8 字符串。

生成“规范编码”时,RDNSequence 中每个项目的值都会转换为 UTF-8,并使用标签

0x0c
重新编码为 UTF-8 字符串。这发生在
asn1_string_canon
函数
中。此外,还应用了以下转换:

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

这就是您需要做的全部。

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

© www.soinside.com 2019 - 2024. All rights reserved.