Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring引导导致自签名证书的SSL对等握手失败_Java_Macos_Curl_Spring Boot_Keytool - Fatal编程技术网

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测试了它们

  • 唯一的钥匙工具-最快的一个

    删除现有的myapp.jks并使用这些参数通过keytool重新生成

    keytool-genkeypair-dname“cn=Name姓氏,ou=MyUnit,o=MyOrg,c=US”-别名MyOrg-keypass 123456-storepass 123456-validity 365-keyalg RSA-keystore myapp.jks

  • 只有openssl

    通过名为“myapp.p12”的openssl创建pkcs文件

    openssl pkcs12-inkey myapp-key.pem-in-myapp-csr.pem-export-out-myapp.p12

    将application.yml密钥存储:“myapp.jks”更改为密钥存储:“myapp.p12”

  • 它们的组合(当前方法)

    通过名为“myapp.p12”的openssl创建pkcs文件

    openssl pkcs12-inkey myapp-key.pem-in-myapp-csr.pem-export-out-myapp.p12

    将其导入jks文件

    keytool-importkeystore-srckeystore myapp.p12-srcstoretype pkcs12-destkeystore myapp.jks-deststoretype jks


  • “我已经创建了一个GitHub项目…”很抱歉,但这样做的目的是在你的项目离开GitHub很久以后成为一种资源。这就是为什么问题必须是自足的,不应该依赖外部资源。请在您的问题中包含您的密码。谢谢@JimGarrison-但我有!如果您手头有一个模板化+功能化的Spring Boot web应用程序,您可以复制我的确切版本。我不打算粘贴运行Spring启动应用程序所需的~10个样板源代码文件,这就是为什么我在GitHub上费劲地提供了一个。在我的项目离开GitHub很久之后,我在上面粘贴的所有内容对任何观众来说都是有意义和有用的。如果你仍然不同意我在这里说的任何话,请让我知道你认为在这种情况下,什么会构成MCVE/SSCCE。另外,请重新考虑你的DV/CV,考虑到我在这里提供的所有信息,这有点苛刻。如果问题离题,则应提供SE简历。如果你只是觉得这是一个糟糕的问题,就应该给予DVs。就我个人而言,我不认为这两种情况都是如此,但你当然可以不同意。@smeeb投票结果接近的原因有很多,而“离题”只是其中之一。谢谢@Mehmet(+1)!!!答案非常棒,我最终选择了选项1(仅适用于keytool),它在一开始就运行得非常好。也谢谢你的礼貌、礼貌和尊重,不像其他在这些看板上走动的居民。。。