Mutual Authentication(Two-Way TLS/SSL) with cloud residing KeyStores and TrustStores(Secret Manager) -Spring boot

huangapple go评论65阅读模式
英文:

Mutual Authentication(Two-Way TLS/SSL) with cloud residing KeyStores and TrustStores(Secret Manager) -Spring boot

问题

我正在研究在Spring Boot中实现**双向认证(Mutual Authentication)**,我已经在本地实现并且正常运行。但我想从Amazon/Google证书管理器或者S3存储桶中获取证书/密钥库。

***之前的配置***
因为我之前在本地有存储,我可以通过以下方式获取它们:
```yaml
# ApplicationProperties.yaml
server.ssl.enabled=true
# 密钥库
server.ssl.key-alias=1
server.ssl.key-store=classpath:clientKeystore.p12
server.ssl.key-store-password=whatever

# 信任库
server.ssl.trust-store=classpath:clientTrustStore.p12
server.ssl.trust-store-password=possiblyAnything
server.ssl.client-auth=need

RestTemplate配置

@Value("${server.ssl.trust-store}")
private String trustStorePath;
@Value("${server.ssl.trust-store-password}")
private String trustStorePass;
@Value("${server.ssl.key-store}")
private String keyStorePath;
@Value("${server.ssl.key-store-password}")
private String keyStorePass;
@Value("${server.ssl.key-alias}")
@Bean
public RestTemplate restTemplate() {
    SSLContext sslContext = null;
    SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
    sslContext = new SSLContextBuilder()
            .loadKeyMaterial(keystore, keyStorePassword)
            .loadTrustMaterial(trustStore, new TrustSelfSignedStrategy())
            .build();
    HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslSocketFactory).build();
    HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
    requestFactory.setHttpClient(httpClient);
    return new RestTemplate(requestFactory);
}

> 现在这些信任库和密钥库都在云上,我想在应用加载/启动时获取它们。

我非常困惑为什么我们在配置(appProperties)和sslContext中都使用了这些存储。它们之间有什么区别?<br> 我不能只在sslContext中设置它们吗?如果可以的话,我可以从云中获取它们,将其处理为密钥库和信任库,然后立即设置它们。

是否有更好的工作方法?<br>
如果我说的不够清楚,还请谅解,我刚开始接触安全领域,仍在摸索中。<br>
<br>
还有一个问题

  • 在典型的客户端服务器设置(多个服务器)中,如果我希望与server1使用双向TLS,而与server2使用无SSL的HTTP通信,该怎么办?

<details>
<summary>英文:</summary>

&lt;br/&gt;I&#39;m working on **Mutual Authentication in spring boot** and I could implement it locally and its running smooth.&lt;br/&gt;But I wanted to get certificates/stores from Amazon/Google certificates manager or may be from s3 bucket.

***Previous Configuration***
&lt;br/&gt;As I have stores locally, this way i could get them

#ApplicationProperties.yaml
server.ssl.enabled=true
#KeyStore
server.ssl.key-alias=1
server.ssl.key-store=classpath:clientKeystore.p12
server.ssl.key-store-password=whatever

#TrustStore
server.ssl.trust-store=classpath:clientTrustStore.p12
server.ssl.trust-store-password=possiblyAnything
server.ssl.client-auth=need

***RestTemplate Configuration***
@Value(&quot;${server.ssl.trust-store}&quot;)
private String trustStorePath;
@Value(&quot;${server.ssl.trust-store-password}&quot;)
private String trustStorePass;
@Value(&quot;${server.ssl.key-store}&quot;)
private String keyStorePath;
@Value(&quot;${server.ssl.key-store-password}&quot;)
private String keyStorePass;
@Value(&quot;${server.ssl.key-alias}&quot;)

@Bean
public RestTemplate restTemplate()
{
SSLContext sslContext = null;
SSLConnectionSocketFactory sslSocketFactory =
new SSLConnectionSocketFactory(sslContext,NoopHostnameVerifier.INSTANCE);
sslContext = new SSLContextBuilder()
.loadKeyMaterial(keystore, keyStorePassword)
.loadTrustMaterial(trustStore,new TrustSelfSignedStrategy())
.build();
HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslSocketFactory).build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
return new RestTemplate(requestFactory);
}


&gt; Now the same truststores and keystores are in the cloud, and i want to
&gt; fetch them at Application load/start time.

&lt;br/&gt;
I&#39;m really confused Why are we using stores both in config(appPropeties) and in sslContext. Whats the difference ? &lt;br&gt; Can&#39;t I just set them at sslContext alone ? If i can do that, i can just fetch them from cloud, process it into keystore and truststore, set them right away.
&lt;br/&gt;
*Is there a better working approach?*
&lt;br/&gt;
Pardon if this looks lame, I&#39;m new to security so still i&#39;m figuring out how things work.&lt;br&gt;
&lt;br&gt;
**Also one more question**

 - In a typical Client Server setting(Multiple servers), what if i want to communicate with server1 on mutual TLS and server2 on http(without ssl)



</details>


# 答案1
**得分**: 1

这种情况可能会发生在您的应用程序需要信任由您正在通信的其他应用程序使用的证书,而这些证书由同一公司管理。在这种情况下,您可以在本地创建一个信任存储并使用它。您不需要为通常用于网站的公司签名的证书。

您不需要在两个地方设置密钥库/信任库。我更喜欢设置密钥库和信任库的方式:

```java
@Configuration
public class SSLConfig {
    @Autowired private Environment env;

    @PostConstruct
    private void configureSSL() {
        System.setProperty("javax.net.ssl.keyStore", env.getProperty("server.ssl.key-store"));
        System.setProperty("javax.net.ssl.keyStorePassword", env.getProperty("server.ssl.key-store-password"));
        System.setProperty("javax.net.ssl.trustStore", env.getProperty("server.ssl.trust-store"));
        System.setProperty("javax.net.ssl.trustStorePassword", env.getProperty("server.ssl.trust-store-password"));
    }
}

application.properties 文件中:

server.ssl.key-store=keystores/client.jks
server.ssl.key-store-password=changeit
server.ssl.trust-store=keystores/mycustom.truststore
server.ssl.trust-store-password=changeit
英文:

It could happen that your application have to trust certificates that are used by another applications you are communicating with, and that is managed by the same company. In this case you can create a truststore locally and use it. You don't need certificates signed by a company that are used in general for websites.

You don't need to set keystore/truststore in both the places. My preferred way to set the keystore and truststore:

@Configuration
public class SSLConfig {
    @Autowired private Environment env;

    @PostConstruct
    private void configureSSL() {
        System.setProperty(&quot;javax.net.ssl.keyStore&quot;, env.getProperty(&quot;server.ssl.key-store&quot;));
        System.setProperty(&quot;javax.net.ssl.keyStorePassword&quot;, env.getProperty(&quot;server.ssl.key-store-password&quot;));
        System.setProperty(&quot;javax.net.ssl.trustStore&quot;, env.getProperty(&quot;server.ssl.trust-store&quot;));
        System.setProperty(&quot;javax.net.ssl.trustStorePassword&quot;, env.getProperty(&quot;server.ssl.trust-store-password&quot;));
    }
}

In the application.properties:

server.ssl.key-store=keystores/client.jks
server.ssl.key-store-password=changeit
server.ssl.trust-store=keystores/mycustom.truststore
server.ssl.trust-store-password=changeit

答案2

得分: 1

差异在于上游和下游配置。

application.properties:

当您在application.properties中使用server.ssl.*时,实际上是在配置您的服务器端。也就是说,您正在创建server.port以接受具有指定server.ssl.key的https流量。server.ssl.client-auth=need指定客户端的浏览器(或另一个应用程序)应使用客户端证书进行身份验证。而server.ssl.trust-store则指定了可信客户端的证书。

sslContext:

当您使用sslContext时,您正在配置您的Java应用程序从外部服务进行出站连接。您使用loadKeyMaterialloadTrustMaterial来在您的应用程序中使用一些第三方服务。loadTrustMaterial指定了您信任的服务器证书,而loadKeyMaterial指定了您的应用程序应该用于连接到某些资源的密钥。

英文:

The difference is in upstream and downstream configuration.

application.properties:

When you use application.properties with server.ssl.* you are actually configures your server side. I.e. you are creating server.port to accept https traffic with specified server.ssl.key. server.ssl.client-auth=need specifies that client's browser (or another app) should use client certificate to pass authentication. And server.ssl.trust-store specifies trusted client's certificates.

sslContext:

When you use sslContext you are configuring your outbound connections from your java app to outside services. And you use loadKeyMaterial and loadTrustMaterial for use some third-party service in your app. loadTrustMaterial specifies which server certificates you are trusting and loadKeyMaterial specifies which key your app should use to connect to some resource.

huangapple
  • 本文由 发表于 2020年10月18日 02:50:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/64406149.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定