java.lang.Exception: Public 回复和密钥库中的密钥不匹配
java.lang.Exception: Public keys in reply and keystore don't match
我必须访问托管在 443.Service 端口的 Web 服务,提供商已与我们共享三个证书。
- ABCD.cer
- CA_Certificate.cer
- CCA_Certificate.cer
我必须通过为 SSL 创建表单链将它们添加到密钥库 communication.I 已执行以下步骤。
keytool -keystore npci_keystore_test.jks -genkey -alias npci_client_testore
Result :- keystore npci_keystore_test.jks created.
keytool -import -keystore npci_keystore_test.jks -file CA_Certificate.cer -alias theCARoot
Result :- certificate CA_Certificate.cer is added to keystore.
keytool -import -keystore npci_keystore_test.jks -file CCA_Certificate.cer -alias theCCARoot
Result :- certificate CCA_Certificate.cer is added to keystore.
keytool -import -keystore npci_keystore_test.jks -file ABCD.cer -alias npci_client_testore
在第 4 步我有以下异常
输入密钥库密码:(当我输入密码时出现以下异常)
keytool 错误:java.lang.Exception:Public 回复中的密钥和密钥库不匹配
我已经在 SO 中进行了搜索,但到目前为止还没有成功。
我正在按照以下来源创建商店并在其中导入证书。
JKS Keystore
编辑:---
我已经通过更改证书的导入顺序进行了测试,但到目前为止没有成功。
您问题中的 link 解释了如何为服务器创建 SSL 密钥库,这不是您想要做的。您所做的是:
- 创建新的密钥对
- 将受信任的证书添加到密钥库
- 将另一个受信任的证书添加到密钥库
- 尝试导入服务器的 SSL 证书作为您的密钥对的证书
第 4 步失败,因为 SSL 证书是为完全不同的密钥对生成的。
三个证书大概是:
- 网络服务的SSL证书
- 签署 SSL 证书的 CA 证书
- 签署 CA 的根证书
您现在要做的是将信任锚添加到您的信任库(默认情况下:${JAVA_HOME}/jre/lib/security/cacerts
),结果是您的客户端接受 Web 服务的 SSL 证书。
通常SSL服务器在SSL握手期间将除根证书之外的整个链发送给客户端。这意味着您必须将根证书添加到您的信任库:
keytool -import -keystore ${JAVA_HOME}/jre/lib/security/cacerts -file CCA_Certificate.cer -alias theCCARoot
如果 web 服务需要 SSL 客户端身份验证,则需要额外的步骤,但您从未提到过客户端身份验证,因此我认为没有必要。
这里的问题是您在导入证书时使用的别名与您在创建 JKS 商店时使用的别名相似。只需更改别名即可解决您的问题。源文档[1]需要相应修改。
[1] http://docs.oracle.com/cd/E19509-01/820-3503/ggfgo/index.html
在我的例子中,链中缺少 "The root certificate that signed the CA"。请检查您是否有适当的 ROOT CA 证书,否则将其从中间导出并导入到密钥库中。将根 CA 导入我的密钥库对我有用。
在第 4 点(出现错误:keytool 错误:java.lang.Exception:Public 回复和密钥库中的密钥不匹配)在您导入证书的地方,请更改别名。别名不应为 npci_client_testore,因为它已被用作密钥库的别名。
这对我有用:
keytool -keystore yourkeystorename -importcert -alias certificatealiasname -file certificatename.cer
我在托管 Tomcat8 时遇到了相同的异常错误(密钥库不匹配)。如果您在创建密钥库时输入了 wrong domain name
或 no domain name
,您将需要再次重新创建密钥库文件并再次将您的 CSR 重新提交给您的证书颁发机构 (CA) licensed/recognised/approved 以颁发数字签名证书(在我的例子中是 Godaddy)。
以下是创建密钥库文件的命令:
keytool -keysize 2048 -genkey -alias tomcat -keyalg RSA -keystore tomcat.keystore
keytool -importkeystore -srckeystore tomcat.keystore -destkeystore tomcat.keystore -deststoretype pkcs12
(当提示要求名字和姓氏时,您需要输入域名,它要求完全合格的域名 (FDQN) 例如 www.example.com)。来自城市、州和省 - do not abbreviate
输入以下命令创建 CSR(从与您的 tomcat.keystore 位置相同的目录):
keytool -certreq -keyalg RSA -alias tomcat -file myFQDN.csr -keystore tomcat.keystore
注意:由于之前的“密钥库不匹配”错误,我不得不从 windows 控制台 (MMC) 中删除所有 Godaddy 证书。
一旦您的证书颁发机构准备好您的证书文件。下载文件并双击 2 个 .crt 文件中的每一个以在 windows 中再次重新安装它们(选择自动安装在本地计算机中)。确保备份 tomcat.keystore 文件,然后 按顺序 将这些证书文件导入 tomcat.keystore 文件(从头开始),顺序与以下示例相同:
keytool -import -alias root -keystore tomcat.keystore -trustcacerts -file gdig2.crt.pem
keytool -import -alias intermed -keystore tomcat.keystore -trustcacerts -file gd_bundle-g2-g1.crt
keytool -import -alias tomcat -keystore tomcat.keystore -trustcacerts -file namewithnumbersandletters.crt
确保您已更新 server.xml 然后重新启动 Tomcat
<Connector port="80" protocol="HTTP/1.1"
relaxedQueryChars="|{}[]%-"
connectionTimeout="20000"
redirectPort="443" />
<Connector SSLEnabled="true" URIEncoding="UTF-8"
clientAuth="false"
keystoreFile="C:\Program Files\Java\jdk-11.0.9\bin\tomcat.keystore"
keystorePass="ChangeToYourPassword"
maxThreads="200"
port="443"
scheme="https"
secure="true"
sslProtocol="TLS"
sslEnabledProtocols="TLSv1.2"
ciphers="TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" />
瞧!在域上浏览时会出现锁定图标(安全连接)。
与@Omikron 的回答类似,我通过将 TrustedRoot.crt
和 DigiCertCA.crt
文件添加到 jre/lib/security/cacerts
密钥库来解决它。
sudo keytool -import -alias ALIAS -file TrustedRoot.crt -storetype JKS -keystore ${JAVA_HOME}/jre/lib/security/cacerts -file DigiCertCA.crt
然后我能够将证书导入我自己的密钥库。
keytool -import -trustcacerts -alias other_alias -file certificate.crt -keystore keystore.jks -keypass "password" -storepass "password1"
当您尝试将证书导入现有的 jks 文件时会发生这种情况,该文件中已经存在相同的别名。如果您想使用相同的别名,请先删除旧别名及其在 jks 中的关联证书,然后再导入新别名。
1 - keytool -delete -alias <alias_name> -keystore <your jks file name>
2 - keytool -import -alias <alias_name> -keystore <your jks file name> -file <your source cer or crt file>
我必须访问托管在 443.Service 端口的 Web 服务,提供商已与我们共享三个证书。
- ABCD.cer
- CA_Certificate.cer
- CCA_Certificate.cer
我必须通过为 SSL 创建表单链将它们添加到密钥库 communication.I 已执行以下步骤。
keytool -keystore npci_keystore_test.jks -genkey -alias npci_client_testore
Result :- keystore npci_keystore_test.jks created.
keytool -import -keystore npci_keystore_test.jks -file CA_Certificate.cer -alias theCARoot
Result :- certificate CA_Certificate.cer is added to keystore.
keytool -import -keystore npci_keystore_test.jks -file CCA_Certificate.cer -alias theCCARoot
Result :- certificate CCA_Certificate.cer is added to keystore.
keytool -import -keystore npci_keystore_test.jks -file ABCD.cer -alias npci_client_testore
在第 4 步我有以下异常
输入密钥库密码:(当我输入密码时出现以下异常)
keytool 错误:java.lang.Exception:Public 回复中的密钥和密钥库不匹配
我已经在 SO 中进行了搜索,但到目前为止还没有成功。
我正在按照以下来源创建商店并在其中导入证书。 JKS Keystore
编辑:---
我已经通过更改证书的导入顺序进行了测试,但到目前为止没有成功。
您问题中的 link 解释了如何为服务器创建 SSL 密钥库,这不是您想要做的。您所做的是:
- 创建新的密钥对
- 将受信任的证书添加到密钥库
- 将另一个受信任的证书添加到密钥库
- 尝试导入服务器的 SSL 证书作为您的密钥对的证书
第 4 步失败,因为 SSL 证书是为完全不同的密钥对生成的。
三个证书大概是:
- 网络服务的SSL证书
- 签署 SSL 证书的 CA 证书
- 签署 CA 的根证书
您现在要做的是将信任锚添加到您的信任库(默认情况下:${JAVA_HOME}/jre/lib/security/cacerts
),结果是您的客户端接受 Web 服务的 SSL 证书。
通常SSL服务器在SSL握手期间将除根证书之外的整个链发送给客户端。这意味着您必须将根证书添加到您的信任库:
keytool -import -keystore ${JAVA_HOME}/jre/lib/security/cacerts -file CCA_Certificate.cer -alias theCCARoot
如果 web 服务需要 SSL 客户端身份验证,则需要额外的步骤,但您从未提到过客户端身份验证,因此我认为没有必要。
这里的问题是您在导入证书时使用的别名与您在创建 JKS 商店时使用的别名相似。只需更改别名即可解决您的问题。源文档[1]需要相应修改。
[1] http://docs.oracle.com/cd/E19509-01/820-3503/ggfgo/index.html
在我的例子中,链中缺少 "The root certificate that signed the CA"。请检查您是否有适当的 ROOT CA 证书,否则将其从中间导出并导入到密钥库中。将根 CA 导入我的密钥库对我有用。
在第 4 点(出现错误:keytool 错误:java.lang.Exception:Public 回复和密钥库中的密钥不匹配)在您导入证书的地方,请更改别名。别名不应为 npci_client_testore,因为它已被用作密钥库的别名。
这对我有用:
keytool -keystore yourkeystorename -importcert -alias certificatealiasname -file certificatename.cer
我在托管 Tomcat8 时遇到了相同的异常错误(密钥库不匹配)。如果您在创建密钥库时输入了 wrong domain name
或 no domain name
,您将需要再次重新创建密钥库文件并再次将您的 CSR 重新提交给您的证书颁发机构 (CA) licensed/recognised/approved 以颁发数字签名证书(在我的例子中是 Godaddy)。
以下是创建密钥库文件的命令:
keytool -keysize 2048 -genkey -alias tomcat -keyalg RSA -keystore tomcat.keystore
keytool -importkeystore -srckeystore tomcat.keystore -destkeystore tomcat.keystore -deststoretype pkcs12
(当提示要求名字和姓氏时,您需要输入域名,它要求完全合格的域名 (FDQN) 例如 www.example.com)。来自城市、州和省 - do not abbreviate
输入以下命令创建 CSR(从与您的 tomcat.keystore 位置相同的目录):
keytool -certreq -keyalg RSA -alias tomcat -file myFQDN.csr -keystore tomcat.keystore
注意:由于之前的“密钥库不匹配”错误,我不得不从 windows 控制台 (MMC) 中删除所有 Godaddy 证书。
一旦您的证书颁发机构准备好您的证书文件。下载文件并双击 2 个 .crt 文件中的每一个以在 windows 中再次重新安装它们(选择自动安装在本地计算机中)。确保备份 tomcat.keystore 文件,然后 按顺序 将这些证书文件导入 tomcat.keystore 文件(从头开始),顺序与以下示例相同:
keytool -import -alias root -keystore tomcat.keystore -trustcacerts -file gdig2.crt.pem
keytool -import -alias intermed -keystore tomcat.keystore -trustcacerts -file gd_bundle-g2-g1.crt
keytool -import -alias tomcat -keystore tomcat.keystore -trustcacerts -file namewithnumbersandletters.crt
确保您已更新 server.xml 然后重新启动 Tomcat
<Connector port="80" protocol="HTTP/1.1"
relaxedQueryChars="|{}[]%-"
connectionTimeout="20000"
redirectPort="443" />
<Connector SSLEnabled="true" URIEncoding="UTF-8"
clientAuth="false"
keystoreFile="C:\Program Files\Java\jdk-11.0.9\bin\tomcat.keystore"
keystorePass="ChangeToYourPassword"
maxThreads="200"
port="443"
scheme="https"
secure="true"
sslProtocol="TLS"
sslEnabledProtocols="TLSv1.2"
ciphers="TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" />
瞧!在域上浏览时会出现锁定图标(安全连接)。
与@Omikron 的回答类似,我通过将 TrustedRoot.crt
和 DigiCertCA.crt
文件添加到 jre/lib/security/cacerts
密钥库来解决它。
sudo keytool -import -alias ALIAS -file TrustedRoot.crt -storetype JKS -keystore ${JAVA_HOME}/jre/lib/security/cacerts -file DigiCertCA.crt
然后我能够将证书导入我自己的密钥库。
keytool -import -trustcacerts -alias other_alias -file certificate.crt -keystore keystore.jks -keypass "password" -storepass "password1"
当您尝试将证书导入现有的 jks 文件时会发生这种情况,该文件中已经存在相同的别名。如果您想使用相同的别名,请先删除旧别名及其在 jks 中的关联证书,然后再导入新别名。
1 - keytool -delete -alias <alias_name> -keystore <your jks file name>
2 - keytool -import -alias <alias_name> -keystore <your jks file name> -file <your source cer or crt file>