具有有效证书的spring boot https获取ERR_SSL_VERSION_OR_CIPHER_MISMATCH,自签名工作正常

Posted

技术标签:

【中文标题】具有有效证书的spring boot https获取ERR_SSL_VERSION_OR_CIPHER_MISMATCH,自签名工作正常【英文标题】:spring boot https with valid cert get ERR_SSL_VERSION_OR_CIPHER_MISMATCH, self signed works fine 【发布时间】:2017-02-10 10:27:43 【问题描述】:

我正在运行 Spring Boot 1.4.0.RELEASE。

我从 IT 部门获得了有效证书。

我使用 IT_cert.cer 生成了一个 tomcat keystore.jks 文件

keytool -keystore tomcat-keystore.jks -storepass password -import -alias "tomcat" -file it_issued_cert.cer

配置我的 application.yml 以打开 SSL

server:
  context-path: /uaa
  port: 9999
  ssl:
      enabled: true
      key-store: classpath:tomcat-keystore.jks
      key-store-password: password
      key-password: password
      enabled-protocols: TLSv1.2 # make sure only to use the latest TLS version

用于签署证书的算法是

Signature algorithm name: SHA256withRSA

当我运行 spring-boot 应用程序时,它会启动并找到我的证书。

当我在 HTTPS 端口上使用 chrome 时,不再有来自浏览器的“不受信任”警告。

但是现在有一个来自 Chrome 和 IE11 的 ERR_SSL_VERSION_OR_CIPHER_MISMATCH 声称我可能正在使用 RC4 加密......

我尝试指定低于 TLSv1.2 的非安全协议并采用默认值。但它们都会导致相同的错误。

我确信最新的 Chrome/IE11 有 TLSv1.2 所以我对浏览器的错误感到困惑。

此外,如果我使用自签名,一切正常,但我收到有关信任自签名的安全警告。

我的结论是我配置证书的方式导致了这个错误,还是我的 IT 部门的签名算法?

【问题讨论】:

【参考方案1】:

近乎欺骗Java SSLHandshakeException: no cipher suites in common

HTTPS 服务器需要私钥和匹配证书,并且根据证书的颁发方式,服务器可能还需要“链”或“中间”证书(有时不止一个) .您导入了一个证书,这还不够。

首先查看您的文件it_issued_cert.cer,看看它是否为 PEM 格式:它是否包含分组为行的所有可读字符,至少一个块以一行开头-----BEGIN sometype_in_caps----- 然后是一些完全由字母、数字、加号+ 和斜线/ 组成的行,最后可能等于=,最后是一行-----END same_type----?

如果 PEM 并且至少有两个块,其中一个具有 [RSA|DSA|EC|ENCRYPTED] PRIVATE KEY 类型,而另一个具有(具有)类型 [X.509|maybesomethingelse] CERTIFICATE,则可以使用 OpenSSL 转换为 PKCS12,然后使用 keytool 转换为 JKS。首先检查是否需要任何“链”或“中间”证书:如果文件已经包含多个证书并且不是由完整的 doofus 准备的,那么这些多个证书形成所需的 chai,请继续。如果文件只包含一个证书,请使用openssl x509 -in $file -noout -subject -issuer 确保主题是您的服务器并查看颁发者;如果发行人是您环境中受信任的 CA(如“我的公司 CA”),请继续。否则,询问 IT 是否需要任何链证书,以 PEM 格式获取它们,并将它们添加到文件中。然后做:

openssl pkcs12 -export -in $file -out new.p12 -friendlyname alias_you_want

(编辑)自 8u60 以来的 Java(在 2015 年——甚至在我写原始答案之前)默认接受 PKCS12 密钥库,如果配置,早期版本可以这样做。对于需要 JKS 的早期版本,然后执行(拼写更正,aszahran 评论):

keytool -importkeystore -srckeystore new.p12 -srcstoretype pkcs12 -destkeystore new.jks 
# on Java versions that need JKS, it is the default type
# but can specify -deststoretype jks if you want

如果文件是 PEM,但只有一个类型为 CERTIFICATE 的块,或者如果文件根本不是 PEM,则该证书必须是为响应某人的 CSR(证书签名请求)而颁发的:

如果您向他们提供了 CSR,请提供详细信息(编辑您的问题)您如何以及在何处生成 CSR。那是私钥所在的位置,您需要使用该密钥、复制它或转换(和复制)它,具体取决于您所做的。

如果您没有向他们提供 CSR,请询问他们从哪里获得的。如果他们自己生成了密钥和 CSR,请向他们索要 PEM 格式的密钥。如果他们从其他人那里获得 CSR,请向其他人索要 PEM 格式的密钥。一旦你得到它,将它添加到文件中,然后返回到上面的案例。如果他们坚持给您提供 PEM 格式以外的其他内容,请提供详细信息。

如果没有人拥有此证书的私钥,则无法使用该证书。丢弃它并重新开始。

【讨论】:

是的,就是这样...我没有使用来自 CSR 的私钥作为导入的一部分,它给出了来自 Chrome 的 ERR_SSL_VERSION_OR_CIPHER_MISMATCH 错误 这就是我生成 jks 的方法:keytool -importkeystore -srckeystore temp.p12 -srcstoretype PKCS12 -destkeystore new.jks -deststoretype JKS

以上是关于具有有效证书的spring boot https获取ERR_SSL_VERSION_OR_CIPHER_MISMATCH,自签名工作正常的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot使用阿里云证书启用HTTPS

spring boot 与 vue 配置 https

Spring Boot如何配置SSL实现https协议

如何使用证书在 Spring Boot 中调用 https Web 服务

Https系列之二:https的SSL证书在服务器端的部署,基于tomcat,spring boot

使用 Spring Boot/Spring Security 对 LDAP 进行证书身份验证