This tutorial explains to you about authenticating and securing internal communication between micro-services using 2-Way-TLS authentication. Before understanding 2-way-TLS, you must know 1-way-TLS, its handshake process, usage, creating self-signed certificates & implementation. So in this tutorial series, we have covered everything so the learner can directly move from novice to expert.
Table of Content:
- What is TLS?
- TLS v/s SSL
- Terminology
- A brief explanation of the 1-Way-TLS handshake process with a diagram
- Where 1-Way-TLS is used?
- Creating Service-1 using SpringBoot with one endpoint(without TLS/Encryption)
- Creating Self Signed Certificate
- Enable HTTPS on Service1 i.e. Enable 1-Way-TLS
- Result of hitting the endpoint using a browser without installing the certificate on a client machine
- Result of hitting the endpoint using browser after installing the certificate on a client machine
- Creating Service2 using SpringBoot and call Service-1's endpoint from Service2
Github Link:
- Git clone https://github.com/joyshah/service1.git
- Git clone https://github.com/joyshah/service2.git
1. What is TLS?
2. TLS v/s SSL?
TLS is an improved version of SSL(Secured Socket Layer). SSL word has become so common that even today we use SSL for end-to-end encryption but actually, we are using TLS. The below image depicts everything.
3. Terminology
- Certificate: A certificate contains a public key and a name. The certificate may also have an expiration date, the name of the certifying authority that issued the certificate, organization info to which certificate issued, a serial number, encryption algorithm details and optional additional information. Most importantly, it contains the digital signature of the certificate issuer.
- KeyStore: A KeyStore stores server keys i.e. public key and private key, along with the signed certificate. We can store a list of server keys, along with the signed certificate. It is required only when a server is running on a TLS connection. It is used to prove its own identity to its counterpart.
- TrustStore: A TrustStore is kind of KeyStore which stores one or more certificate also knows as a public key. It is used to store the certificates of trusted entities and to verify a counterpart's identity. A process can maintain a store of certificates of all its trusted parties which it trusts.
4. A brief explanation of the 1-Way-TLS handshake process with a diagram
- The client will send a SYNC J request to the server to initiate TCP Connection.
- The server will respond with SYNC K, ACK J+1 response.
- The client will respond to the server with an ACK K+1 response.
- The client sends a "ClientHello" message, which includes the version of SSL/TLS a client is capable of, what cipher suites it supports, and any compression types available.
- The server responds to the client with "ServerHello" which includes the same information as the client and sends the server's certificate to the client. Server certificate includes information such as Organization Information, Issuer Information, Certificate Validity, Public Key, Signature, Encryption Algorithm Details & other optional information.
- The client verifies the server certificate is valid by using the CA certificate present in its KeyChain(Mac) or Microsoft Management Console(Windows), we can say that this is the browser's trust store. Note, in this part, we are not going to use CA(Certificate Authority) rather we will export the self signed server certificate itself in the trust store. By this process, we can make sure that the server is authenticated and the imposter is not conducting the man-in-middle attack.
- If the certificate is found valid, the client will generate a pre-master key, encrypt it with Server Certificate's Public Key and send it to the server. Please note pre-master key is not a session key. The session key is never transmitted between client and server, but it's generated by the client and server at their end using Diffie-hellman or variants of the Diffie-hellman algorithm.
- The server will decrypt the pre-master key shared by the client using the server certificate's private key, which would be only with the server. Now the server will generate the session key using the decrypted pre-master key and use it for further communication with the client. The client generates a session key as it already has the pre-master key.
- Now that the handshake has been established and the session key has been exchanged, data exchange between client and server can be encrypted and decrypted using the shared session key. This symmetric cryptography will secure the remainder of application-to-application communication.
5. Where 1-Way-TLS is used?
6. Creating Service-1 using SpringBoot with one endpoint(without TLS/Encryption)
-
https://start.spring.io/
-
Give the "Service-1" as artifact name
-
Click on add dependencies button and select spring web
dependency.
-
Keep other things default and click on generate
button.
-
Create a package name with controller and a class
SSLTestController.java, and paste the below code to create an
endpoint.
Or you can clone it from
"https://github.com/joyshah/service1"
package com.example.service1.contoller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class SSLTestController { @GetMapping public String getData() { return "Hello World, This is Service 1"; } }
Hitting http://localhost:8081(In my case, I am using 8081 port, you can change the port by the overriding server.port=8081 in the application.properties file) in the browser will return the above data as shown above.
7. Creating Self Signed Certificate
To create a self-signed certificate, we will be using the below KeyTool command which will generate the "keystore_server_1.jks" file. Let's understand the keytool command options used for generating server certificates:
- genkeypair option of KeyTool means generate a key pair that is private and public key
- KeyStore option is used to name generated jks file. Here you can provide any file name.
- JKS file can contain more than one key pair/certificate, so an alias is used to reference that exact key pair in the KeyStore.
- storepass and keypass are passwords. storepass is used to access KeyStore by using you can all the information of certificate except "key pair's private key" while keypass is used to get particular key pair's private key.
- keyalg specifies the algorithm to be used to generate the key pair, and keysize specifies the size of each key to be generated.
- Validity is the validity of the certificate in days which generates two fields to "Not Valid Before" and "Not Valid After".
Command:
-alias server_1 \
-keystore keystore_server_1.jks \
-storepass secret \
-keypass secret \
-keyalg RSA \
-keysize 2048 \
-validity 3650 \
-deststoretype pkcs12 \
-ext KeyUsage=digitalSignature,dataEncipherment,keyEncipherment,keyAgreement \
-ext ExtendedKeyUsage=serverAuth,clientAuth \
Please note that the JKS format is a proprietary format and commonly used with java world. A different open-source format such as PCKS12 is open source and is not specific to java. However, it is possible to convert formats.
- What is your first and last name? -> Joy Shah
- What is the name of your organizational unit? -> microservicetutorial org
- What is the name of your organization? -> microservicetutorial org
- What is the name of your City or Locality? -> Bangalore
- What is the name of your State or Province? -> Karnakata
- What is the two-letter country code for this unit? -> IN
- Is CN=Joy Shah, OU=microservicetutorial org, O=microservicetutorial org, L=Bangalore, ST=Karnakata, C=IN correct? -> Yes
Once the above process completes, you will find "keystore_server_1.jks" in your current directory. To see the content inside the JKS file, we can use the below command. It will list all the certificates present in the JKS file. Once you execute the below command, it will ask you for the KeyStore password that is the StorePass password you gave while generating the JKS file.
keytool -v -list -keystore keystore_server_1.jks
8. Enable HTTPS on Service1 i.e. Enable 1-Way-TLS
To enable 1-Way-TLS/HTTPS in Service1, we have to enable the SSL server and need to add certificate information such as certificate path, StorePass, and KeyPass as shown below in application.properties file. You can copy and paste generated keystore_server_1.jks under resource/static directory.
server.port=8081 server.ssl.enabled=true server.ssl.key-store=classpath:static/keystore_server_1.jks server.ssl.key-password=secret server.ssl.key-store-password=secret
9. Result of hitting the endpoint using a browser without installing the certificate on a client machine
Even after enabling TLS on service1 and started hitting URL with HTTPS still, we are getting the "not secure" exclamatory icon because the browser is unable to authenticate the certificate as the certificate is not present in KeyChain(Mac) or Microsoft Management Console(Windows). In this scenario, even though all the communication will be encrypted and secure, but we could not authenticate the responding server, that is to say, we could not distinguish response is from an actual real server or response is from an imposter/Man-In-Middle.
As you can see in the below image, the server responded with a server certificate, but as I said earlier, we don't have a certificate to authenticate the server certificate is from the actual server or from the impersonator.
10. Result of hitting the endpoint using browser after installing the certificate on a client machine
- --exportcert option of keytool is used for exporting the certificate.
- -file option is to specify a name for the newly generated certificate file.
- -keystore defines the server certificate, which has public as well private keys, from which we will export a server certificate without the private key.
- -storepass is a password to access the keystore file that is keystore_server_1.jks file.
- -alias is used to refer particular certificate from the list of certificates present in keystore_server_1 .jks file.
- -rfc option makes the certificate printable as RFC 1421 specification. You can open .cer file even in text editors.
3. Once you import the certificate, double click on imported certificate to open certificate detail window.
11. Create Service2 using SpringBoot and calling Service-1's endpoint
- https://start.spring.io/
- Give the "Service-2" as artifact name
- Click on add dependencies button and select spring web dependency.
- Keep other things default and click on generate button.
- Create a package with name "controller" and inside that create a class namely SSLTestController.java, and paste the below code to create an endpoint. Or you can clone it from "https://github.com/joyshah/service2"
package com.example.service2.controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;@RestControllerpublic class SSLTestController {@GetMapping("/withoutTrustStore")public String getDataFromService1WithoutTrustStore() {RestTemplate restTemplateWithoutTrustStore = new RestTemplate();try {return restTemplateWithoutTrustStore.getForEntity("https://localhost:8081", String.class).toString();} catch (Exception e) {return e.getMessage();}}}
server.port=8082
server.port=8082 client.ssl.trustStore=classpath:static/truststore_server_2.jks client.ssl.trustStore.password=secret client.ssl.version=TLSv1.3
package com.example.service2.config; import org.apache.http.client.HttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.ssl.SSLContextBuilder; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; import javax.net.ssl.SSLContext; @Configuration public class StartUpConfig { @Value("${client.ssl.trustStore}") private Resource trustStore; @Value("${client.ssl.trustStore.password}") private String trustStorePassword; @Value("${client.ssl.version}") private String sslVersion; @Bean public RestTemplate getRestTemplate() { final SSLContext sslContext; try { sslContext = SSLContextBuilder.create() .loadTrustMaterial(trustStore.getFile(), trustStorePassword.toCharArray()) .setProtocol(sslVersion) .build(); } catch (Exception e) { throw new IllegalStateException("Failed to setup client SSL context", e); } final HttpClient httpClient = HttpClientBuilder.create() .setSSLContext(sslContext) .build(); final ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); return new RestTemplate(requestFactory); } }
@Autowired private RestTemplate restTemplate; @GetMapping("/withTrustStore") public ResponseEntity<String> getDataFromService1OverTLS() { return restTemplate.getForEntity("https://localhost:8081", String.class); }
Woohoo! Finally, the Service2(i.e. Client) is able recognize/authenticate the Service1(i.e. TLS enabled Server) and we are getting response successfully from Service1 to Service2 and from Service2 to browser.
As shown in the above figure, we have not turned on SSL/TLS for Service2 but SSL/TLS is enabled for Service1. Hence, the communication between Service2 and Service1 is authenticated and encrypted using a self-signed certificate but it's insecure between Browser and Service2. We can carry out steps no.7 to 10 for Service2 to enable SSL/TLS.
A look at the best free slot machines - Dr.MCD
ReplyDeleteFree slot machines from the list of 제천 출장마사지 the 영천 출장안마 best free casinos online 시흥 출장마사지 today. Check out our 보령 출장샵 guide on the best free casinos and slot 경상북도 출장샵 machines of 2021.