带有 URI 片段的 SAN 证书

带有 URI 片段的 SAN 证书

我需要生成带有 SAN URI 的 TLS 证书,其中 URI 有一个片段(有一个哈希“#”)。但是当我尝试使用 openssl 生成证书时,片段被删除了。

# generate key and CSR for client certificate
openssl req -nodes -new -keyout me.key -out me.csr -subj "/O=Acme/CN=me"

# sign cert
openssl x509 -req -in me.csr -CA My-CA.crt -CAkey My-CA.key -set_serial 01 -out me.crt -extfile <(echo 'subjectAltName=URI:https://my.example/profile#me')

# verify result
openssl x509 -text -noout -in me.crt
#         X509v3 extensions:
#             X509v3 Subject Alternative Name:
#                 URI:https://my.example/profile

我尝试了几种不同的方法来转义该值,但似乎都没有达到预期的效果。我认为转义可能适用于 Common Name 等字段,但不适用于 SAN 部分。

我愿意接受 openssl 替代方案。但如果能看到一个可用于验证其是否有效的概念验证证书,那就更好了。

注意:这本质上是 WebID-TLS 的要求(https://www.w3.org/2005/Incubator/webid/spec/tls/#dfn-webid_certificate)。虽然可以使用没有片段的 URL 作为 WebID,但不建议这样做,而且需要额外的工作。绝对应该支持它。

答案1

OpenSSL 配置中的井号被视为注释的开头,无论配置是在实际文件中给出还是通过动态生成。如果您想将其包含在 SAN 中,则需要转义或引用该井号,以防止将其视为注释的开头。引用后它看起来像这样:

... -extfile <(echo 'subjectAltName="URI:https://my.example/profile#me"')

或逃脱:

... -extfile <(echo 'subjectAltName=URI:https://my.example/profile\#me')

答案2

您可以改用配置文件来定义 SAN:

subjectAltName = @alt_names

[alt_names]
URI.1 = http://example.test/some\#thing

相关内容