【问题标题】:Hash algorithm for certificate / CRL directory证书/CRL目录的哈希算法
【发布时间】:2015-12-04 18:50:54
【问题描述】:

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

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

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

【问题讨论】:

标签: openssl


【解决方案1】:

哈希格式没有记录,所以这很可能会改变——事实上,它已经改变了一次。 x509 command 支持选项-subject_hash-issuer_hash 以及-subject_hash_old-issuer_hash_old。此描述适用于从 OpenSSL 1.0.1f 开始的“新”哈希格式。

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

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

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

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

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

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

这就是你需要做的所有事情。

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

【讨论】:

  • 所以我发现自己处于完全相同的情况 - 你能帮我举个例子吗?正如 openssl 报告的那样:issuer=C = US, O = U.S. Government, OU = DoD, OU = PKI, CN = DOD JITC ID CA-43 |哈希 = d7fc5635。我认为 SHA-1 哈希必须以 3556fcd7 开头,但我不确定如何根据颁发者进行规范编码。
  • 我最终写了an implementation in Erlang
  • 啊,这很有帮助。谢谢!
猜你喜欢
  • 2021-02-17
  • 1970-01-01
  • 2016-06-23
  • 1970-01-01
  • 2012-09-20
  • 1970-01-01
  • 2011-12-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多