带URI片段的SAN TLS证书生成问题:OpenSSL丢失哈希片段的解决需求
带URI片段的SAN TLS证书生成问题:OpenSSL丢失哈希片段的解决需求
我太懂你这个头疼的问题了——想用OpenSSL生成带哈希片段(#)的URI作为Subject Alternative Name(SAN)的TLS证书,结果每次#后面的内容都被自动截断,试了各种转义都不管用,尤其是这还是WebID-TLS规范推荐的做法,确实让人挠头。
问题根源
OpenSSL在解析扩展配置时,默认把未被引号包裹的#当作注释符号,哪怕它出现在URI中间也不例外。所以你之前直接写URI:https://my.example/profile#me时,#me会被当成注释直接忽略,只保留#前面的部分。
解决方法
下面给你两种可行的方案,亲测有效:
方案1:使用单独的扩展配置文件(推荐)
这种方式最稳妥,避免shell和OpenSSL的解析冲突:
- 创建一个扩展配置文件,比如命名为
san_ext.cnf,内容如下:
subjectAltName = URI:"https://my.example/profile#me"
这里关键是把整个URI用双引号包裹起来,让OpenSSL把#当作URI的一部分,而不是注释。
- 用这个配置文件签名证书:
openssl x509 -req -in me.csr -CA My-CA.crt -CAkey My-CA.key -set_serial 01 -out me.crt -extfile san_ext.cnf
方案2:命令行进程替换(适合快速测试)
如果不想单独建文件,也可以在命令行里给URI加上双引号,注意用单引号包裹整个echo内容,避免shell解析干扰:
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"')
验证结果
运行你之前的验证命令,检查输出:
openssl x509 -text -noout -in me.crt
现在应该能看到完整的SAN字段:
X509v3 Subject Alternative Name:
URI:https://my.example/profile#me
额外:生成CSR时就指定正确的SAN
如果想在生成CSR阶段就包含带片段的URI,可以创建一个请求配置文件req_ext.cnf:
[req] distinguished_name = req_distinguished_name req_extensions = v3_req [req_distinguished_name] O = Acme CN = me [v3_req] subjectAltName = URI:"https://my.example/profile#me"
然后生成CSR和密钥:
openssl req -nodes -new -keyout me.key -out me.csr -config req_ext.cnf
这样后续签名时,CSR里已经包含了正确的SAN信息,也可以用-extfile参数覆盖。
备注:内容来源于stack exchange,提问作者Rich Remer
相关产品推荐
相关产品推荐

