我需要生成带有 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