我创建了GitHub project that perfectly reproduces这里解释的一切。
我正在构建一个Spring Boot应用程序(带有一个嵌入式Jetty Web容器),并且我试图让它在本地运行时提供自签名的OpenSSL证书(当在登台或prod环境中运行时,该应用程序将为root提供服务CA签名证书。
因此,要创建SSL功能,首先我通过发出:
创建public key/CSRopenssl 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属性更新了我的application.yml
:
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}
-k
是故意忽略SSL ,因为这是一个自签名证书。无论有没有-k
我都尝试过,结果是一样的。
我看到evidence that this could be a MacOS issue for some reason,但坦率地说,我甚至不确定从哪里开始寻找。我创建公钥/私钥对的方式有问题吗?我将公钥/ CSR导入JKS文件的方式有问题吗?我配置的任何方面都有问题吗?
答案 0 :(得分:1)
要执行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
所以基本上你的配置是正确的,除了在密钥库中缺少私钥。
答案 1 :(得分:1)
我可以详细说明解决方案。有3个解决方案。我用你的代码和java 8测试了它们。
只有keytool - 最快的一个
删除现有的myapp.jks并使用这些参数通过keytool重新生成。
keytool -genkeypair -dname“cn =姓名姓氏,ou = MyUnit,o = MyOrg,c = US”-alias 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
答案 2 :(得分:-1)
这一切都没有意义。
openssl
。您需要使用keytool
,而不是其他内容,如下所示:
keytool -genkey ...
keytool -selfcert ...
两次使用相同的别名。
keytool -export ...
keytool -import ...
进入客户&#39; truststore 文件。