Java Spring引导导致自签名证书的SSL对等握手失败
我已经创建了一个在这里解释的一切Java Spring引导导致自签名证书的SSL对等握手失败,java,macos,curl,spring-boot,keytool,Java,Macos,Curl,Spring Boot,Keytool,我已经创建了一个在这里解释的一切 我正在构建一个Spring Boot应用程序(带有嵌入式Jetty web容器),并试图让它在本地运行时提供自签名OpenSSL证书(在临时或prod环境中运行时,该应用程序将提供根CA签名证书) 因此,为了创建SSL功能,首先我通过以下方式创建了: openssl req -x509 -newkey rsa:4096 -keyout myapp-key.pem -out myapp-csr.pem -days 3650 然后我创建了JKS并导入了我的公钥,
我正在构建一个Spring Boot应用程序(带有嵌入式Jetty web容器),并试图让它在本地运行时提供自签名OpenSSL证书(在临时或prod环境中运行时,该应用程序将提供根CA签名证书) 因此,为了创建SSL功能,首先我通过以下方式创建了:
openssl req -x509 -newkey rsa:4096 -keyout myapp-key.pem -out myapp-csr.pem -days 3650
然后我创建了JKS并导入了我的公钥,如下所示:
keytool -importcert -trustcacerts -file myapp-csr.pem -alias myorg -keystore myapp.jks
然后,我用SSL属性更新了我的:
ssl:
key-store: 'myapp.jks'
key-store-password: '123456'
key-password: '123456'
然后我运行我的Spring Boot应用程序:
./gradlew build && java -Dspring.config=. -jar build/libs/spring-boot-troubleshooting.jar
到目前为止还不错——启动时没有错误/异常/警告。然后,我打开一个新终端并运行:
curl -k -H "Content-Type: application/json" -X GET https://localhost:9200/health
curl: (35) SSL peer handshake failed, the server most likely requires a client certificate to connect
如果我切换回运行应用程序的终端,我现在会在控制台输出中看到:
06:14:00.149 [qtp1706099897-15] WARN org.eclipse.jetty.http.HttpParser - Illegal character 0x16 in state=START for buffer HeapByteBuffer@5b876b3[p=1,l=175,c=8192,r=174]={\x16<<<\x03\x01\x00\xAa\x01\x00\x00\xA6\x03\x03ZL\xBa\xF8T\x86r...\x00\x05\x01\x00\x00\x00\x00\x00\x12\x00\x00\x00\x17\x00\x00>>>-Type: applicatio...\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}
06:14:00.149[qtp1706099897-15]警告org.eclipse.jetty.http.HttpParser-状态为开始缓冲区的非法字符0x16HeapByteBuffer@5b876b3[p=1,l=175,c=8192,r=174]={\x16类型:应用程序…\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}
-k
是有意忽略SSL,因为这是一个自签名证书。我尝试了使用和不使用-k
两种方法,结果是相同的
我明白了,但坦率地说,我甚至不知道从哪里开始寻找。我创建公钥/私钥对的方式有问题吗?我将公钥/CSR导入JKS文件的方式有问题吗?我的配置还有其他问题吗?这些都没有意义
- 您根本不需要使用
openssl
- CSR不是证书,更不用说公钥了
- 将CSR导入密钥库的结果不是有效的密钥库,因为没有私钥
键工具
,无需其他操作,如下所示:
keytool-genkey…
keytool-selfcert…
两次使用相同的别名keytool-导出…
keytool-导入…
到客户端的信任库文件中要执行SSL握手,服务器密钥库必须同时包含公钥和私钥。最简单的方法是创建一个带有私钥和证书的
p12
捆绑包,并使用importkeystore
命令同时导入它们
openssl req -x509 -newkey rsa:4096 -keyout myapp-key.pem -out myapp-csr.pem -days 3650 -subj '/CN=localhost'
openssl pkcs12 -export -in myapp-csr.pem -inkey myapp-key.pem -out keystore.p12
keytool -importkeystore -deststorepass 123456 -destkeystore keystore.jks -srckeystore keystore.p12 -srcstoretype PKCS12
现在,您可以使用curl
查询服务器
curl -k -H "Content-Type: application/json" -X GET https://localhost:9200/health
curl --cacert myapp-csr.pem -H "Content-Type: application/json" https://localhost:9200/health
所以基本上您的配置是正确的,除了密钥库中缺少私钥。@EJP很好地解释了根本原因。myapp.jks文件中没有私钥 我能说出详细的解决方案。有三种解决方案。我用您的代码和Java8测试了它们
“我已经创建了一个GitHub项目…”很抱歉,但这样做的目的是在你的项目离开GitHub很久以后成为一种资源。这就是为什么问题必须是自足的,不应该依赖外部资源。请在您的问题中包含您的密码。谢谢@JimGarrison-但我有!如果您手头有一个模板化+功能化的Spring Boot web应用程序,您可以复制我的确切版本。我不打算粘贴运行Spring启动应用程序所需的~10个样板源代码文件,这就是为什么我在GitHub上费劲地提供了一个。在我的项目离开GitHub很久之后,我在上面粘贴的所有内容对任何观众来说都是有意义和有用的。如果你仍然不同意我在这里说的任何话,请让我知道你认为在这种情况下,什么会构成MCVE/SSCCE。另外,请重新考虑你的DV/CV,考虑到我在这里提供的所有信息,这有点苛刻。如果问题离题,则应提供SE简历。如果你只是觉得这是一个糟糕的问题,就应该给予DVs。就我个人而言,我不认为这两种情况都是如此,但你当然可以不同意。@smeeb投票结果接近的原因有很多,而“离题”只是其中之一。谢谢@Mehmet(+1)!!!答案非常棒,我最终选择了选项1(仅适用于keytool),它在一开始就运行得非常好。也谢谢你的礼貌、礼貌和尊重,不像其他在这些看板上走动的居民。。。