我的问题与此类似:Tomcat 无法在密钥库中找到密钥条目
我有一个 CER 文件,我使用以下命令将其导入 JKS:
keytool -importcert -file codesign_Base64.cer -keystore imported_keystore.jks -alias my_alias
然后我在 standalone.xml 中为 jBoss 添加了下面一行配置。
<subsystem xmlns="urn:jboss:domain:web:1.1" native="false" default-virtual-server="default-host">
<connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http" redirect-port="8443"/>
<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" enable-lookups="false" secure="true">
<ssl name="ssl" key-alias="my_alias " password="change_this" certificate-key-file="C:\Programs\Siemens\JBoss7.1.0\domain\configuration\imported_keystore.jks " protocol="TLSv1" verify-client="false"/>
</connector>
<virtual-server name="default-host" enable-welcome-root="false">
<alias name="localhost"/>
<alias name="example.com"/>
</virtual-server>
</subsystem>
这样,当我尝试启动应用程序时,我会在 jBoss 日志文件中看到以下错误消息,这些消息描述了此类错误。
11:46:19,692 ERROR [org.apache.coyote.http11.Http11Protocol] (MSC service thread 1-4) Error initializing endpoint: java.io.IOException: Alias name mykey does not identify a key entry
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeyManagers(JSSESocketFactory.java:517) [jbossweb-7.0.10.Final.jar:]
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.init(JSSESocketFactory.java:452) [jbossweb-7.0.10.Final.jar:]
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.createSocket(JSSESocketFactory.java:168) [jbossweb-7.0.10.Final.jar:]
at org.apache.tomcat.util.net.JIoEndpoint.init(JIoEndpoint.java:977) [jbossweb-7.0.10.Final.jar:]
at org.apache.coyote.http11.Http11Protocol.init(Http11Protocol.java:190) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.connector.Connector.init(Connector.java:983) [jbossweb-7.0.10.Final.jar:]
at org.jboss.as.web.WebConnectorService.start(WebConnectorService.java:267) [jboss-as-web-7.1.0.Final.jar:7.1.0.Final]
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_75]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_75]
at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_75]
但是如果我探索 Java 密钥存储区的内容,我仍然可以看到相应密钥的存在。
C:\Programs\Siemens\JBoss7.1.0\domain\configuration>keytool -list -keystore C:\Programs\Siemens\JBoss7.1.0\domain\configuration\winstore.jks
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 1 entry
my_alias, Jun 23, 2017, trustedCertEntry,
Certificate fingerprint (SHA1): 8D:64:10:8B:F6:0D:1E:17:01:52:1C:97:8A:89:75:80:2D:2F:45:6B
当我尝试使用 P7B 证书时,我也遇到了类似的问题。到目前为止,唯一可行的方法是手动生成证书 - 自签名证书。这显然不是组织前进的策略。
请告诉我这里可能遗漏了什么。我上面包含的类似帖子似乎暗示了只有证书而没有密钥的情况,我无法将其联系起来。
任何指点肯定会有帮助,因为我已经在多个地方发布了此信息,但目前没有收到任何回复。
谢谢,帕万。
答案1
不,您的密钥库不包含私钥。看到上面写着什么了吗trustedCertEntry
?受信任的证书不是私钥,它只是证书,而证书不是私钥。SSL/TLS 服务器需要私钥和匹配的证书链;证书本身不能用于执行协议,因此您的服务器无法接受任何 HTTPS 连接,因此任何尝试使用 HTTPS 连接的浏览器(可能是从 HTTPS 重定向后)都会失败。P7B 也不包含私钥,尽管它可以包含多个证书,而 CER 通常只包含一个。(相比之下,客户通常只需要 CA“根”证书,而不需要私钥,除非使用相当罕见的“客户端身份验证”选项。)
你需要一个privateKeyEntry
包含私钥和证书链的该密钥和您想要的主机名。对于 Java,有两种方法(及其变体)可以实现此目的:
1:用于keytool
在 JKS 中生成新的私钥(带有虚拟自签名证书)并为其创建 CSR(证书签名请求,或简称为 Cert[ificate] Req[uest])。提交 CSR 和其他所需内容(例如向证书颁发机构 (CA) 付款)以获取合适的证书,通常附带至少一个“链”或“中间”证书,客户可能需要这些证书才能信任该证书。用于keytool
导入证书/链进入相同的 JKS 和已经包含私钥的条目(替换虚拟的自签名证书);您也可以选择将链证书导入为 Trustedcert 条目。
方法 1 是规范的,而且在我看过的每个证书供应商(包括 CA 和经销商)的网站上都有描述,而且通常都是重复的;我不知道您怎么会错过所有这些描述。请注意,这些描述通常是指 Tomcat,这是最广泛使用的基于 Java 的 Web 服务器;Jboss Web 服务器组件(现在称为 Wildfly)实际上是 Tomcat 的一个分支。以下是谷歌找到我的前两个方法:
*https://www.digicert.com/csr-creation-java.htm
*https://knowledge.symantec.com/support/ssl-certificates-support/index?page=content&id=INFO227
2A:使用其他工具(如 Windows 或 MacOS 或 OpenSSL)生成私钥,并从 CA 获取合适的证书(通常使用 CSR)并包含其链。如果适用,将私钥和证书链导出/转换/合并到 PKCS12 文件中(在 Microsoft 中也称为 PFX),然后可能使用它来keytool -importkeystore
将 PKCS12 转换为 JKS。(在 Java 8 中,在许多情况下,您实际上可以直接使用 PKCS12,而无需将其转换为 JKS,并且 Java 9 有望鼓励这样做。)
2B:如果你已经生成私钥并使用其他工具获取合适的证书/链,只是将它们放入 PKCS12 中并可能转换为如上所述的 JKS。
请注意,其他一些 GUI(如 Microsoft、MacOS 和 Firefox)专注于证书:它们将受信任的其他证书显示为“证书”,将私钥加证书组合显示为“带私钥的证书”。但区别仍然很重要;服务器必须拥有私钥,并尝试使用“证书没有privatekey' 失败。Java 却有不同类型的密钥库条目 —— 尽管对于某些密钥库来说,这些类型实际上并未直接存储。