Demand – Story

In the project, encrypted file transmission is required. Considering security, SFTP transmission scheme is abandoned (port 22 is vulnerable to attack). Due to the nature of the project, cloud storage is not possible, so we decide to use HTTPS encryption for transmission. Among them, to ensure safety, we need to do the following to ensure:

  • Source encryption

Use AES encryption stream to encrypt files

  • Information transmission channel encryption

Encrypt the transport channel using HTTPS

  • Application layer encryption

Authenticate requests using RSA

Information transfer channel encryption -Https

There are a lot of theories about HTTPS, but today we’ll just talk about the real thing. To support HTTPS, you need to apply for a certificate and configure it with the application. Among them, the authentication is divided into one-way authentication and two-way authentication, the author also wondered at the beginning, what is one-way authentication and two-way authentication?

Here’s a picture to illustrate:

Ok, without further ado, let’s do it! Today we use the JDK’s own keytool to generate a certificate.

Use keytool to generate an authentication certificate

1.1 Generate the keystore file containing the Public key and Private key in JKS format keytool -genkey -alias serverA -keystore D:\tmp\key\serverKeystore.jks -keypass javaee123* -storepass javaee123* -keyalg RSA -keysize 512 -validity 3650 -v -dname "CN = 127.0.0.1,O = BTC,DC = Server Https,DC = CN,OU = China" 1.2. Export the server certificate alias server from the keystore keytool -export -alias serverA -keystore D:\ TMP \key\serverKeystore. JKS -storepass javaee123* - the file server. The cer 1.3. Import server.cer into the client trust certificate library clientTrustStore. JKS. keytool -import -alias trustServer -file server.cer -keystore clientTruststore.jks -storepass javaee123* / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / 1.1. Generate a keystore file containing Public and Private keys on the server side in JKS format. keytool -genkey -alias clientA -keystore D:\tmp\key\clientKeystore.jks -keypass javaee123* -storepass javaee123* -keyalg Rsa-keysize 512-validity 3650 -v -dname "CN = 127.0.0.1,O = BTC,DC = Client Https,DC = CN,OU = China" 1.2. Export the client certificate whose alias is client from the keystore keytool -export -alias clientA -keystore D:\ TMP \key\ clientKeyStore. JKS -storepass Javaee123 * - file client. Cer 1.3. Import client.cer into the server trust certificate library serverTrustStore. JKS. Cer -keystore serverTrustStore. JKS -storepass javaee123* Serverkeystore.jks ServerTrustStore. JKS Client: clientKeystore.jks clientTrustStore.jksCopy the code

Create a folder and follow the above 6 instructions to generate the certificate. You’ll get files like this:

Configure HTTPS in the project

server

Upload the JKS file for the serverresourcedirectory

Configure the certificate in applicaton.yml
server:
  port: 9000
  tomcat:
    uri-encoding: UTF-8
  ssl:
    key-store: classpath:serverKeystore.jks
    key-store-password: javaee123*
    key-store-type: JKS
    trust-store: classpath:serverTruststore.jks
    trust-store-password: javaee123*
    trust-store-type: JKS
    client-auth: need
Copy the code

client

Add client certificates to resource

Configuration of the RestTemplateClientHttpRequestFactory
package com.tea.modules.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.util.ResourceUtils;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * com.jay.company.file.config
 *
 * @author xiejiemin
 * @create2020/9/28 * /
@Configuration
@Slf4j
public class RestTemplateConfig {

    @Bean()
    public RestTemplate restTemplate(ClientHttpRequestFactory httpComponentsClientHttpRequestFactory) {
        RestTemplate restTemplate = new RestTemplate(httpComponentsClientHttpRequestFactory);
        restTemplate.getMessageConverters().set(1.new StringHttpMessageConverter(StandardCharsets.UTF_8));
        log.info("loading restTemplate");
        return restTemplate;
    }

    @Bean("httpComponentsClientHttpRequestFactory")
    public ClientHttpRequestFactory httpComponentsClientHttpRequestFactory(a) throws IOException, UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
        final String allPassword = "javaee123*";
        TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
        SSLContext sslContext = SSLContextBuilder
                .create()
                .loadKeyMaterial(ResourceUtils.getFile("classpath:clientKeystore.jks"),
                        allPassword.toCharArray(), allPassword.toCharArray())
                .loadTrustMaterial(ResourceUtils.getFile("classpath:clientTruststore.jks"), allPassword.toCharArray())
                .build();
        HttpClient client = HttpClients.custom()
                .setSSLContext(sslContext)
                .build();
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(client);
        returnrequestFactory; }}Copy the code
Jar to import
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.6</version>
        </dependency>
Copy the code

Points to be aware of

When generating a certificate, set the user name to the IP address of the server. For example, I have 127.0.0.1

rendering