OpenSSL 能够使用 CA 证书和 CRL 的特定目录结构。如果您将目录名称作为第三个参数传递给
SSL_CTX_load_verify_locations
(如这个问题中所述),它将在此目录中查找 CA 证书以验证客户端证书。它通过获取客户端证书颁发者的哈希值并附加一个整数来找到正确的 CA 证书,例如34bb8598.0
。通常,这些名称是指向真实文件的符号链接,并且符号链接是使用 c_rehash
工具创建的。
同样,OpenSSL 可以将证书吊销列表存储在此类目录中,如此问题中所述,并通过证书颁发者的哈希值查找正确的吊销列表。
现在,我需要让一个程序重用这样的CRL目录。该程序不使用 OpenSSL,因此我需要以其他方式生成这些哈希值。生成这些散列文件名的算法是什么?
哈希格式没有记录,所以这可能会改变——事实上,它已经改变过一次。
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)
0x30
(十进制 48)
0x06
证书中给出的字符串值可以用多种不同类型表示,例如带有标签
0x13
的“可打印字符串”、带有标签 0x16
的“IA5 字符串”或带有标签 0x0c
的 UTF-8 字符串。
生成“规范编码”时,RDNSequence 中每个项目的值都会转换为 UTF-8,并使用标签
0x0c
重新编码为 UTF-8 字符串。这发生在 asn1_string_canon
函数中。此外,还应用了以下转换:
0x20
)。这就是您需要做的全部。
请注意,某些相关字段的 ASN.1 定义不允许使用 UTF-8 字符串(例如,国家/地区代码仅限于“可打印字符串”),因此您可能无法使用 ASN.1 编码直接图书馆。