怎么为你的springboot应用程序配置TLS和HTTP/2

7 篇文章 0 订阅
2 篇文章 0 订阅

使用TLS和HTTP/2保护SpringBoot应用程序

现在,通过HTTPS(TLS)使用安全连接和更高效的HTTP/2协议应该是所有web应用程序的理所当然的事情。您可以从Let's Encrypt获取经过域验证的证书,而无需设置传输层安全性(TLS)。HTTP服务器和web浏览器已经广泛采用HTTP/2。从Java 9和Spring Boot 2/Spring 5开始,您可以轻松地让web应用程序使用安全的HTTPS/TLS连接和HTTP/2协议。

作为一名开发人员,大部分时间您都在本地环境中工作,不能在这里使用任何经过正式验证的TLS证书。相反,开发人员正在使用不安全连接或自签名证书,从而导致浏览器警告。通过设置私有证书颁发机构(CA),您将能够使用安全连接,而不会出现这些恼人的浏览器警告。

在接下来的部分中,您将逐步了解如何实现这一点。

HTTP/2协议

根据规范,您可以在两种变体中使用HTTP/2协议:

明文HTTP上的HTTP/2(h2c)

加密HTTPS上的HTTP/2(h2)

实际上,所有的web浏览器都只支持第二种变体HTTP/2而不是HTTPS(h2)。

因此,您必须遵循以下路径,使用带有TLS(传输层安全性)的HTTPS连接来保护您的web应用程序。

TLS公司

当你读到HTTPS的时候,你总是会偶然发现SSL或TLS这两个术语。

这通常是误解的开始:

HTTP安全(HTTPS)基本上是通过TLS连接的HTTP。

安全套接字层(SSL)是TLS的前身,因此不推荐使用,也不安全。所有SSL版本(1.0、2.0、3.0)都易受攻击,不应再使用。

传输层安全性(TLS)作为SSL的后继协议应该用于HTTPS。目前,TLS 1.3是与tls1.2一起使用的,它仍然与兼容性相关。

使用HTTPS连接提供以下保护层:

加密:所有交换的数据都是加密的,因此没有人可以通过“监听”连接来获取您的数据。

数据完整性:交换的数据在传输过程中不能被修改或损坏而不被检测到。

认证:证明您与预期的网站进行了通信。这就是为什么除了私钥/公钥加密之外还需要证书的原因

我们将按照以下步骤建立有效的TLS连接:

生成强私钥和公钥

创建证书签名请求(CSR)并将其发送到证书颁发机构(CA)

在webserver中安装CA提供的证书(即在spring boot应用程序的嵌入式tomcat中使用java密钥存储)。

在这篇博文中,我将关注当地的发展。因此,在步骤2中,您不会将CSR发送到正式CA。相反,我们将在下一节中设置我们的私有证书颁发机构。

设置私有证书颁发机构(CA)

系统要求

您需要以下软件来执行此博客文章的所有步骤:

首先,您至少需要一个Java 9 JDK或更新版本(JDK 11是下一个长期的替代方案)

此外,为了生成证书和执行签名请求,您需要作为JDK一部分的keytool。

通常,您使用自签名证书进行本地开发。但这些证书总是在web浏览器中生成警告,并将所有请求标记为不安全。

目前,web浏览器还为具有验证警告的TLS证书启用HTTP/2协议。但是作为一个安全意识强的开发人员,当你看到这样的警告时,你应该总是感到害怕。

因此,要消除此警告,您必须创建一个受web浏览器信任的证书。为此,我们必须建立自己的私有证书颁发机构(CA)。使用专用证书颁发机构,以后可以颁发根证书。

最后,可以将此根证书作为新的颁发机构导入到web浏览器中,并用它签署服务器证书。

根CA的证书

开始之前,请先创建以下子目录:

 

  • root-ca  (You will store all artifacts required for setting up a certificate authority here)
  • server (You will store all artifacts required for your signed server certificate here)

在第一步中,您需要为根CA生成私钥/公钥和相应的证书。稍后,您将在服务器证书的签名部分中使用此根证书。

1

keytool -genkeypair -keyalg RSA -keysize 3072 -alias root-ca -dname "CN=My Root CA,OU=Development,O=My Organization,C=DE" -ext BC:c=ca:true -ext KU=keyCertSign -validity 3650 -keystore ./root-ca/ca.jks -storepass secret -keypass secret

This command creates a new java keystore ca.jks in folder root-ca containing the private and public keys. The certificate uses the RSA algorithm with a bit length of 3072 and is valid for 10 years. This includes also the distinguished name CN=My CA,OU=Development,O=My Organization,C=DE.

Now you export the certificate to file ca.pem in the subdirectory root-ca using this command:

 

1

keytool -exportcert -keystore ./root-ca/ca.jks -storepass secret -alias root-ca -rfc -file ./root-ca/ca.pem

Signed Server Certificate

In the next step you create another new java key store file containing the private/public keys for the server certificate.
The private key is required to generate the certificate signing request. The CA uses the public key for validating the certificate signing request.

 

1

keytool -genkeypair -keyalg RSA -keysize 3072 -alias localhost -dname "CN=localhost,OU=Development,O=My Organization,C=DE" -ext BC:c=ca:false -ext EKU:c=serverAuth -ext "SAN:c=DNS:localhost,IP:127.0.0.1" -validity 3650 -keystore ./server/server.jks -storepass secret -keypass secret

You can find the new java key store server.jks in the subdirectory server. Again we use the RSA algorithm with a bit length of 3072 and set it valid for 10 years.

Now you will continue with the generation of the signing request for your server certificate. This creates the file server.csr in the subdirectory server.

 

1

keytool -certreq -keystore ./server/server.jks -storepass secret -alias localhost -keypass secret -file ./server/server.csr

With the next command, you will now sign and export your server certificate using the file server.csr from the previous step.

 

1

keytool -gencert -keystore ./root-ca/ca.jks -storepass secret -infile ./server/server.csr -alias root-ca -keypass secret -ext BC:c=ca:false -ext EKU:c=serverAuth -ext "SAN:c=DNS:localhost,IP:127.0.0.1" -validity 3650 -rfc -outfile ./server/server.pem

To achieve the required valid chain of trust between the root ca and the signed server certificate you have to perform the following last step.

 

1

2

keytool -importcert -noprompt -keystore ./server/server.jks -storepass secret -alias root-ca -keypass secret -file ./root-ca/ca.pem

keytool -importcert -noprompt -keystore ./server/server.jks -storepass secret -alias localhost -keypass secret -file ./server/server.pem

This imports the certificate for the root ca and updates the existing (unsigned) server certificate with the signed one.
Finally, we have a java key store containing the full chain of certificates ready to be used in our spring boot application.

Using the Keytool to manually perform all steps for creating the certificates is good for learning. But if you want to automate these things for subsequent usages then mkcert is a great tool for that.

Import Root CA Certificate into a web browser

Let’s continue with enabling trust in your web browser for our private certificate authority.
We will use the chrome browser here to demonstrate this. Just open the settings in chrome, expand the “Advanced” section and then go to “Manage certificates“.
Here you import the root ca certificate from file ./root-ca/ca.pem into the browser as a new authority. Don’t forget to mark the first checkbox as shown in the following picture.

 

Create Spring Boot Application

In an earlier blog post, I have described how easy you can create a new web application with basic security in just 5 minutes.
You follow the same steps by using start.spring.io, but this time we will use Kotlin instead of Java.

 

To get simple feedback when testing our simple application just add the following rest controller class DemoController to our new spring boot application.
This just prints out an “It works” in the browser when navigating to localhost:8080.

 

1

2

3

4

5

6

@RestController

class DemoController {

 

@GetMapping("/")

fun index() = "It works"

}

But still, we are using unsecured HTTP connections here. It is time for you to change this just now!

Configure TLS

To enable TLS put the following entries into your application.properties file.

 

1

2

3

4

5

6

7

server.port=8443

server.ssl.enabled=true

server.ssl.key-store=classpath:server.jks

server.ssl.key-store-type=PKCS12

server.ssl.key-store-password=secret

server.ssl.key-alias=server

server.ssl.key-password=secret

With these property entries you will change the following behavior:

  • The application is started on port 8443 instead of port 8080 (by convention this is the usual port for HTTPS connections).
  • Use our new java key store server.jks which is of type PKCS12 and is opened with given store password
  • Define the alias of public/private key to use for the server certificate with the corresponding key password

Important: Please do not forget to copy the java key store file server.jks you have created in the previous section into the src/main/resource folder of the new spring boot application.

Configure HTTP/2

You can now switch on HTTP/2 by adding the following entry to application.properties.

 

1

server.http2.enabled=true

Configure Security

Before we can start our application we need to tweak the security configuration a bit.
The reasons for manually configuring this are:

  1. We want to switch off HTTP Strict Transport Security (HSTS) for local development. If we leave this enabled (the default setting for HTTPS connections in spring security) all our applications running on localhost will be forced to use HTTPS by the web browser. This may not be the desired behavior – especially for other local applications that are not configured for HTTPS connections.
  2. You can authenticate yourself to our application by using either basic authentication or form based login
  3. All requests are secured by default (i.e. require authentication first)
  4. We want to have our own user with encrypted password instead of default one (using clear text password)

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

@Configuration

class WebSecurityConfiguration : WebSecurityConfigurerAdapter() {

 

override fun configure(http: HttpSecurity) {

http.headers().httpStrictTransportSecurity().disable() // (1)

.and().httpBasic().and().formLogin() // (2)

.and().authorizeRequests().anyRequest().authenticated() // (3)

}

 

@Bean // (4)

fun myUserDetails(): UserDetailsService = InMemoryUserDetailsManager (

User.withUsername("user")

.password("secret")

.passwordEncoder { passwordEncoder().encode(it) }

.roles("USER")

.build()

)

 

@Bean

fun passwordEncoder(): PasswordEncoder

      = PasswordEncoderFactories.createDelegatingPasswordEncoder()

}

Let’s try it

Now start the spring boot application and after successful start direct your browser to URL https://localhost:8443.
Here you will notice the secure HTTPS connection shown as valid by the browser.

After providing the user credentials “user” and “secret” you will get the message “it works“.

 

That’s it for this tutorial on Spring Boot Apps with HTTP/2 and TLS.

You can grab the complete accompanying project code from my GitHub repository at https://github.com/andifalk/ssl-demo.

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot是一个非常流行的Java Web框架,它简化了Java应用程序的开发和部署过程。 RabbitMQ是一个开源的消息代理,它支持多种协议,包括AMQP、STOMP和MQTT等。TLS协议则是一种加密传输协议,它可以保证数据在传输过程中的安全性。 在Spring Boot应用程序中使用RabbitMQ需要引入相应的依赖,可以使用Maven或Gradle来进行管理。同时,为了保证消息的安全传输,我们可以使用TLS协议对消息进行加密传输。 以下是使用Spring Boot和RabbitMQ进行消息传输并加密的简单示例: 1. 引入依赖 在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-rsa</artifactId> </dependency> ``` 2. 配置RabbitMQ和TLS 在application.properties文件中添加以下配置: ```properties spring.rabbitmq.host=localhost spring.rabbitmq.port=5671 spring.rabbitmq.username=user spring.rabbitmq.password=password spring.rabbitmq.ssl.enabled=true spring.rabbitmq.ssl.key-store=file:/path/to/keystore spring.rabbitmq.ssl.key-store-password=changeit spring.rabbitmq.ssl.trust-store=file:/path/to/truststore spring.rabbitmq.ssl.trust-store-password=changeit ``` 其中,key-store和trust-store分别为用于TLS加密的密钥库和信任库文件路径,需要根据实际情况进行配置。 3. 发送和接收消息 在Spring Boot应用程序中使用RabbitTemplate来发送和接收消息,示例代码如下: ```java @Service public class RabbitMQService { @Autowired private RabbitTemplate rabbitTemplate; public void send(String message) { rabbitTemplate.convertAndSend("exchange", "routingKey", message); } @RabbitListener(queues = "queue") public void receive(String message) { System.out.println("Received message: " + message); } } ``` 其中,send方法用于发送消息,receive方法用于接收消息。在这个例子中,我们将消息发送到名为exchange的交换机,使用名为routingKey的路由键进行路由,然后将消息发送到名为queue的队列中进行消费。 以上就是在Spring Boot应用程序中使用RabbitMQ和TLS进行消息传输的简单示例。需要注意的是,这只是一个基本的示例,实际应用中还需要进行更多的配置和处理,以确保消息传输的安全和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值