简体   繁体   English

如何在 spring 引导中使用非密码保护 (.p12) ssl 证书

[英]how to use non password protected (.p12) ssl certificate in spring boot

I have a.pem certificate which I have to use in my spring boot application.我有一个 .pem 证书,我必须在我的 spring 启动应用程序中使用它。 Now, since java does not understand.pem format, I am converting it to.p12 format.现在,由于 java 不理解.pem 格式,我将其转换为.p12 格式。

Since, we already have a.pem certificate which is not protected by any password, I am trying to avoid password for.p12 too.因为,我们已经有一个不受任何密码保护的.pem 证书,所以我也试图避免使用 .p12 的密码。

I created two.p12 files, one is with password using below command:我创建了两个.p12 文件,一个是使用以下命令的密码:

openssl x509 -signkey sslcert.key  -in sslcert.csr   -req -days 365
-out sslcert.pem

And another without password using below command:另一个没有密码使用下面的命令:

openssl pkcs12  -inkey sslcert.key  -in sslcert.pem  -export -passout
pass: -nokeys -out sslcert.p12

And I am able to get the results successfully using the one with password using the below properties in spring boot application:而且我能够使用 spring 启动应用程序中的以下属性使用带有密码的结果成功获得结果:

server.port=8443  
server.ssl.enabled=true 
server.ssl.key-store-type=PKCS12 
server.ssl.key-store=keys/sslcert.p12 
server.ssl.key-store-password=password

But when I am trying to use the one without password which is my preference, I am getting sslhandshake exception.但是当我尝试使用我喜欢的没有密码的那个时,我得到了 sslhandshake 异常。

And also, I am not able to figure out how to pass this information to spring boot that ssl is not password protected.而且,我无法弄清楚如何将此信息传递给 spring 启动 ssl 没有密码保护。

SO far I tried many combinations like not passing password property or keeping it empty but it failed in all cases.到目前为止,我尝试了许多组合,例如不传递密码属性或将其保留为空,但在所有情况下都失败了。

server.port=8443 
server.ssl.enabled=true
server.ssl.key-store-type=PKCS12
server.ssl.key-store=keys/sslcert.p12

I am getting below exception:我得到以下异常:

javax.net.ssl.SSLHandshakeException: no cipher suites in common
    at sun.security.ssl.Handshaker.checkThrown(Unknown Source)
    at sun.security.ssl.SSLEngineImpl.checkTaskThrown(Unknown Source)
    at sun.security.ssl.SSLEngineImpl.writeAppRecord(Unknown Source)
    at sun.security.ssl.SSLEngineImpl.wrap(Unknown Source)
    at javax.net.ssl.SSLEngine.wrap(Unknown Source)
    at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.flush(SslConnection.java:864)
    at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.fill(SslConnection.java:515)
    at org.eclipse.jetty.server.HttpConnection.fillRequestBuffer(HttpConnection.java:331)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:243)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
    at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:411)
    at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:305)
    at org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:159)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
    at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
    at java.lang.Thread.run(Unknown Source)

SO, can any one throw some light on how to use non-password protected.p12 certificate in spring boot.所以,任何人都可以了解如何在 spring 引导中使用非密码 protected.p12 证书。

All googles articles seems to be telling about the password propected.所有谷歌文章似乎都在讲述预期的密码。 SO is it a mandatory thing in java?那么在 java 中这是强制性的吗?

So after all the research, it seems java key store needs a password.因此,经过所有研究,似乎 java 密钥库需要密码。 So I had to ignore the.p12 which we had without password.所以我不得不忽略我们没有密码的.p12。 And using the pem certificate, we converted it to.p12 with password.并使用 pem 证书,我们将其转换为带有密码的.p12。 And I am doing this from spring code where I am passing random password to shell script which generates.p12 from.pem using that password.我从 spring 代码执行此操作,其中我将随机密码传递给 shell 脚本,该脚本使用该密码从.pem 生成.p12。

And then I am passing the same password to ssl properties from the code.然后我从代码中将相同的密码传递给 ssl 属性。

one drawback is I have to regenerate.p12 from.pem every time application is restarted but this is how I prevent static password.一个缺点是每次重新启动应用程序时我都必须从.pem 重新生成.p12,但这就是我防止 static 密码的方法。

It is not possible wiithout setting password不设置密码是不可能的

By using a custom implementation of WebServerFactoryCustomizer and the BouncyCastle JCE provider, I was able to use a PKCS12 keystore without a password to serve SSL for a spring boot app.通过使用 WebServerFactoryCustomizer 和 BouncyCastle JCE 提供程序的自定义实现,我能够使用没有密码的 PKCS12 密钥库为 spring 引导应用程序提供 SSL。

First I loaded the password-less PKCS12 (in my case, retrieved from Azure Key Vault) into a keystore with the BouncyCastle provider (org.bouncycastle:bcprov-jdk15on):首先,我使用 BouncyCastle 提供程序 (org.bouncycastle:bcprov-jdk15on) 将无密码 PKCS12(在我的情况下,从 Azure Key Vault 检索)加载到密钥库中:

    ByteArrayInputStream keyStoreStream = new ByteArrayInputStream(pfxBytes);

    logger.info("Loading server cert keystore from Vault retrieved cert");
    KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC");
    keyStore.load(keyStoreStream, "".toCharArray());

Then I put the keyStore into an implementation of org.springframework.boot.web.server.SslStoreProvider:然后我把keyStore放到org.springframework.boot.web.server.SslStoreProvider的一个实现中:

public class CustomSslStoreProvider implements SslStoreProvider {

    private KeyStore keyStore;
    private KeyStore trustStore;

    public CustomSslStoreProvider(KeyStore keyStore, KeyStore trustStore){
        this.keyStore = keyStore;
        this.trustStore = trustStore;
    }

And then I registered the CustomSslStoreProvider as a bean so it could be injected into my implementation of WebServerFactoryCustomizer so that it will be used by the embedded server:然后我将 CustomSslStoreProvider 注册为一个 bean,以便可以将它注入到我的 WebServerFactoryCustomizer 实现中,以便嵌入式服务器使用它:

@Component
public class CustomSSLServletContainer implements
        WebServerFactoryCustomizer<TomcatServletWebServerFactory> {


    @Autowired(required = false)
    private CustomSslStoreProvider sslStoreProvider;


    public void customize(TomcatServletWebServerFactory factory) {
        if(sslStoreProvider != null) {
            factory.setSslStoreProvider(sslStoreProvider);
        }

With this implementation, I still configured the key-alias in application.properties (unrelated I happened to require ssl client auth).通过这个实现,我仍然在 application.properties 中配置了密钥别名(无关的,我碰巧需要 ssl 客户端身份验证)。 However, you will not need to provide any of the server.ssl.key-store properties:但是,您不需要提供任何 server.ssl.key-store 属性:

server.ssl.key-alias=panda-asfafa=asfaf
server.ssl.client-auth=need

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM