如何将主题备用名称添加到SSL证书?

56
我正在使用openssl创建自签名证书。在生成的证书中,我遇到了以下错误:
javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present
有人知道在创建证书时如何指定“Subject alternative name”吗? 这是我生成密钥库的方法:
sudo $JAVA_HOME/bin/keytool -genkey -dname "CN=192.168.x.xxx, OU=I, O=I, L=T, ST=On, C=CA" -alias tomcat -validity 3650 -keyalg RSA -keystore /root/.keystore -keypass abcd -storepass abcd

生成密钥的方法:
 openssl s_client -connect 192.168.x.xxx:8443 2>/dev/null

请帮忙!谢谢!

@ Sapphire:我不明白你的问题。主题备用名称在X.509证书中不是必需的扩展。因此,如果您有一个没有它的证书,就没有问题。那么你是怎么得到这个异常的? - Cratylus
@user384706,你能否帮忙看看这个问题?我也不明白为什么会出现这个错误。[http://stackoverflow.com/questions/8759956/failed-to-create-service-exception-javax-xml-ws-webserviceexception/8760118#8760118] - Sapphire
@Sapphire:在另一个帖子中已回复。 - Cratylus
被接受的答案是用Java编写的。如果要使用OpenSSL实现,这里有一个答案:http://security.stackexchange.com/a/91556 - tresf
作为对@Cratylus 2012年早期评论的回应,Chrome现在不再接受通用名称,而是要求使用SAN字段。(短期内,配置更改可以恢复到旧行为。但该设置最终将被删除,强制采用SAN。) - GargantuChet
3个回答

77

虽然这个问题更具体地涉及了Subject Alt. Names中的IP地址,但是命令类似(使用主机名的DNS条目和IP地址的IP条目)。

引用自己的话:

如果您正在使用keytool,从Java 7开始,keytool有一个选项可包含Subject Alternative Name(请参阅文档中的表格-ext):您可以使用-ext san=dns:www.example.com或-ext san=ip:10.0.0.1

请注意,只需Java 7的keytool即可使用此命令。准备好密钥库后,它应该可以与早期版本的Java一起使用。

(此答案的其余部分还提到了如何使用OpenSSL进行操作,但似乎不是您正在使用的方法。)


我无法切换到Java7。在我的Java代码中有没有绕过subjectalternativename检查的方法? - Sapphire
3
请不要回避此检查。就像我说的那样,您只需使用Java 7即可使用此keytool命令。完成后,您应该能够在Java 6(或更低版本)上使用JKS文件(甚至不必在同一台机器上)。或者,您可以使用OpenSSL生成此(自签名)证书(命令和设置可能会更加复杂):您可以将使用OpenSSL生成的PEM密钥/证书转换为.p12文件,并使用密钥库类型PKCS12直接从Java中使用它作为密钥库。您还可以使用主机名而不是IP地址:您可以通过CN轻松完成。 - Bruno
我按照你的建议使用了主机名,但是出现了这个错误:找不到与myhostname.com匹配的名称。 - Sapphire
你需要使用一个已经配置为与该IP地址匹配的主机名(在DNS或hosts文件中)。如果你不熟悉这些概念,安装Java 7可能是最简单的解决方案。 - Bruno
1
我使用 "myip myhostname" 更新了 /etc/hosts 文件,并在证书中使用了 myhostname。 - Sapphire
由于大多数keytool命令都接受扩展(genkeypairgencertgencertreq),我不清楚传播是如何发生的。我的假设是这是一个不断增长的列表,会被链接起来?但我也意识到,在使用genkeypair中的ext以创建签名请求的目的时,不会包括主题备用名称。 - Joe

41

可以使用keytool的附加参数-ext SAN=dns:abc.com,ip:1.1.1.1来指定IP和DNS。

示例:

keytool -genkeypair -keystore <keystore> -dname "CN=test, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown" -keypass <keypwd> -storepass <storepass> -keyalg RSA -alias unknown -ext SAN=dns:test.abc.com,ip:1.1.1.1

11
请注意,上述命令不会创建证书签名请求(CSR)。Java的keytool在密钥库中创建一个自签名证书形式的密钥对,并将SAN属性写入该自签名证书。如果您想发出带有SAN属性的CSR,需要在“keytool -certreq”命令中传递相同的“-ext”参数。有趣的是,keytool的自我记录帮助不包括“-ext”选项,尽管keytool可以正确处理“-ext”。 - avarvit
@avarvit 这意味着即使在调用“-genkeypair”时没有使用,我也可以在CSR中添加altNames。当从CA收到带有此CSR的证书时会发生什么? keytool会导入它并链接到正确的私钥吗?这是一种可能的方法来为缺少altName的证书添加altName吗? - eppesuig
感谢您添加完整的示例。 - Tom

12

生成CSR时可以再次指定-ext属性,以便将其插入到CSR中。

keytool -certreq -file test.csr -keystore test.jks -alias testAlias -ext SAN=dns:test.example.com

完整示例在此处:如何使用keytool创建带有SAN的CSR


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接