To
retrieve employee details securely using TLS 1.2
To retrieve employee details securely using TLS
1.2 from a browser (Google Chrome, Firefox, or Postman), the server and
client (browser) perform a TLS 1.2 handshake to establish a secure
connection. Below is a detailed TLS 1.2 handshake process and how it
works in your web-based Java application.
Scenario Overview
Ø Client:
Google Chrome, Firefox, or Postman
Ø Server:
Apache Tomcat running your Java web service
Ø Endpoint:
/getEmployee REST API to retrieve employee details
Ø Objective:
Securely access https://your-server.com/getEmployee using TLS 1.2.
Ø Key
Exchange Algorithm: ECDHE
Ø Encryption
Algorithm: AES-GCM
Ø Keystore/Truststore:
Configured on Tomcat
Step-by-Step TLS 1.2 Handshake Process
1. Client Hello (Browser → Server)
The browser sends the Client Hello message to
initiate the TLS handshake:
Ø Details
sent:
ü
List of supported TLS versions (including
TLS 1.2).
ü
Cipher suites it supports (e.g.,
ECDHE_RSA_WITH_AES_128_GCM_SHA256).
ü
Random number (Client Random) to be used
for session key generation.
ü
Other extensions, such as SNI (Server
Name Indication) if multiple domains are hosted.
2. Server Hello (Server → Browser)
The server responds with the Server Hello message:
Ø Details
sent:
ü
The chosen TLS version (TLS 1.2).
ü
The chosen cipher suite (e.g.,
ECDHE-RSA-AES128-GCM-SHA256).
ü
Random number (Server Random).
ü
The server's digital certificate (from
its keystore.jks) that contains the public key.
3. Certificate Exchange and Validation (Browser ↔ Server)
Ø Server
sends its certificate to the browser:
ü
The browser checks if the certificate is:
§
Signed by a trusted CA (or self-signed if
using a local truststore).
§
Valid (expiry date, domain match, etc.).
ü
If valid, the handshake proceeds. If not, the
browser shows a certificate warning.
- Optional:
If the server requests a client certificate (for mutual TLS), the
browser will prompt the user to provide one.
4. Key Exchange (ECDHE)
Ø Both
the server and client generate ephemeral keys using the ECDHE
algorithm.
Ø Using
these ephemeral keys along with the Client Random and Server Random,
both parties compute the shared secret session key.
5. Server Finished Message
The server sends a Finished message, encrypted with
the session key, indicating that it has completed its part of the handshake.
6. Client Finished Message
The browser sends a Finished message, encrypted with
the shared session key, indicating that it has completed its part of the
handshake.
7. Secure Communication Begins
ü Now,
the connection is fully encrypted using the AES-GCM cipher suite.
ü The
browser sends an HTTPS GET request for /getEmployee:
Plain text
GET
/getEmployee HTTP/1.1 Host:
your-server.com |
Host: your-server.com
Ø The
server responds with the employee data, encrypted using the same AES-GCM
cipher:
json
{ "employeeId": 101, "name": "Kartik Mandal", "position": "Software
Engineer" } |
Tomcat Configuration for TLS 1.2
Ensure Apache Tomcat is configured to support TLS
1.2 and uses a secure cipher suite.
- Configure
server.xml:
Xml
<Connector
port="8443"
protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true"
maxThreads="150" scheme="https"
secure="true"> <SSLHostConfig> <Certificate
certificateKeystoreFile="/path/to/keystore.jks"
certificateKeystorePassword="password" type="RSA"
/> <Protocols>
<Protocol>TLSv1.2</Protocol> </Protocols> <CipherSuite>ECDHE_RSA_WITH_AES_128_GCM_SHA256</CipherSuite> </SSLHostConfig> </Connector> |
- Keystore
Setup:
ü
Generate the keystore using the following
command:
bash
keytool
-genkey -alias tomcat -keyalg RSA -keystore keystore.jks -keysize 2048 |
How to Verify the TLS 1.2 Connection
1. Using Google Chrome or Firefox
Ø Open
the browser’s developer tools (F12).
Ø Go
to the Security tab.
Ø Check
the connection protocol (should display TLS 1.2) and cipher
suite used.
2. Using Postman
Ø Open
Postman and send a GET request to
https://your-server.com/getEmployee.
Ø Check
the TLS version used in the response details:
ü
Go to Settings → Certificates in
Postman to view more information.
3. Using curl Command (Optional)
You can use curl to verify the TLS version used:
bash
curl -v
--tlsv1.2 https://your-server.com/getEmployee |
To
retrieve employee details securely using TLS 1.3
TLS 1.3 Handshake Process in Browser to Get Employee
Details
In this example, we’ll walk through how a TLS 1.3
handshake secures a web-based Java REST API that retrieves employee
details. The browser and server perform the handshake to establish a secure
connection before data transfer.
Scenario Overview
Ø Client:
Browser (Google Chrome/Firefox) or Postman
Ø Server:
Apache Tomcat hosting a Java REST API
Ø Endpoint:
/getEmployee (API to retrieve employee details)
Ø Objective:
Ensure secure communication using TLS 1.3 with:
ü
ECDHE for key exchange
ü
AES-GCM for encryption
ü
Browser validation of the TLS handshake
TLS 1.3 Handshake Steps
TLS 1.3 simplifies the handshake compared to TLS 1.2 by
reducing the number of round trips and improving security.
1. Client Hello (Browser → Server)
The browser sends a Client Hello message to initiate
the handshake.
Ø Details
sent by the browser:
ü
TLS version: TLS 1.3
ü
Cipher suites: TLS_AES_128_GCM_SHA256 or
TLS_AES_256_GCM_SHA384
ü
Key share: A preliminary public key using
ECDHE (Elliptic Curve Diffie-Hellman Ephemeral) for key exchange.
ü
Random number: Client Random for session
key generation.
ü
Supported Extensions: Such as Server Name
Indication (SNI) to specify the requested domain.
2. Server Hello and Key Exchange (Server → Browser)
The server responds with a Server Hello:
Ø Details
sent by the server:
ü
Chosen cipher suite: e.g., TLS_AES_128_GCM_SHA256
ü
Server Random: Another random number for
session key generation.
ü
Key share: The server’s public key
(ECDHE) to help derive the shared session key.
ü
Digital certificate: Contains the
server’s public key, issued by a trusted Certificate Authority (CA).
3. Session Key Generation
Ø The client
and server compute a shared session key using the ECDHE public keys
and both Random numbers (Client Random + Server Random). I have provided
additional information below.
Ø This
shared session key is used to encrypt communication.
4. Finished Message Exchange
Ø The
server sends a Finished message, encrypted with the shared session key,
indicating it has completed its part of the handshake. I have provided
additional information below.
Ø The
client also sends a Finished message, encrypted with the shared session
key, confirming the handshake is complete.
5. Encrypted Communication Begins
Once the handshake is completed, the browser sends an HTTPS
GET request to retrieve employee details from the server.
Ø Request
sent by the browser:
Plain text
GET
/getEmployee HTTP/1.1 Host:
your-server.com |
Host: your-server.com
Ø Response
from the server:
json
{ "employeeId": 101, "name": "Kartik Mandal", "position": "Software
Engineer" } |
Ø Both
the request and response are encrypted using AES-GCM.
Tomcat Configuration for TLS 1.3
1. Configure server.xml for TLS 1.3
Make sure that Tomcat is configured to use TLS 1.3
only:
xml
<Connector
port="8443"
protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true"
maxThreads="150" scheme="https"
secure="true"> <SSLHostConfig> <Certificate
certificateKeystoreFile="/path/to/keystore.jks"
certificateKeystorePassword="password" type="RSA"
/> <Protocols>
<Protocol>TLSv1.3</Protocol> </Protocols>
<CipherSuite>TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384</CipherSuite> </SSLHostConfig> </Connector> |
2. Generate Keystore for Tomcat
Use the following command to generate a keystore:
bash
keytool
-genkey -alias tomcat -keyalg RSA -keystore keystore.jks -keysize 2048 |
How to Verify the TLS 1.3 Handshake
1. Using Google Chrome/Firefox
Ø Open
your browser and access the API endpoint:
https://your-server.com/getEmployee
Ø Open
Developer Tools (F12) → Security Tab.
ü
Check the Connection section to confirm
the TLS version (1.3) and cipher suite used.
2. Using Postman
Ø Open
Postman and send a GET request to
https://your-server.com/getEmployee.
Ø View
the TLS connection details in Postman settings.
3. Using curl Command
To verify the TLS handshake from the command line, use:
bash
curl -v
--tlsv1.3 https://your-server.com/getEmployee |
Session Key Generation in TLS 1.3 using ECDHE
The session key generation is a critical step in the TLS
1.3 handshake, ensuring confidentiality and forward secrecy. Here's
how the shared session key is computed using the ECDHE public keys
and random numbers (Client Random + Server Random).
How ECDHE Works for Session Key Generation
ECDHE (Elliptic Curve Diffie-Hellman Ephemeral)
allows both the client and server to securely exchange cryptographic keys
without sending the actual session key across the network. Here’s the detailed
breakdown.
Step-by-Step Process
1. Key Pair Generation (Client & Server)
Ø Client
generates an ephemeral key pair:
ü
Private key: Client_Private_Key
ü
Public key: Client_Public_Key
Ø Server
also generates an ephemeral key pair:
ü
Private key: Server_Private_Key
ü
Public key: Server_Public_Key
These ephemeral key pairs ensure that a new key exchange
occurs with every TLS session, providing forward secrecy.
2. Exchange of Public Keys
Ø The client
sends its Client_Public_Key to the server in the Client Hello
message.
Ø The server
sends its Server_Public_Key to the client in the Server Hello
message.
3. Key Exchange Using ECDHE
Both the client and server use their private keys and the
other party’s public key to compute a shared secret.
Ø Client
calculates:
Plain text
Shared_Secret
= ECDH(Client_Private_Key,
Server_Public_Key) |
Ø Server
calculates:
Plain text
Shared_Secret
= ECDH(Server_Private_Key,
Client_Public_Key) |
The shared secret computed by both the client and
server will be identical, thanks to the properties of elliptic curve
cryptography.
4. Session Key Derivation
Once the shared secret is computed, it is used along
with the Client Random and Server Random values to derive the
final session key using a Key Derivation Function (KDF) such as
HKDF.
Ø Session
Key Derivation:
Plain text
Session_Key =
HKDF(Shared_Secret,
Client_Random + Server_Random) |
Ø Purpose
of HKDF:
ü
Extracts randomness from the shared secret.
ü
Derives a cryptographic session key that
will be used to encrypt data.
5. Encryption Begins with AES-GCM
The derived session key is now used with the AES-GCM
encryption algorithm to encrypt and decrypt all communication between the
client and server during the session.
Ø Example:
ü
Browser GET Request: Encrypted with the
session key.
ü
Server Response: Also encrypted with the
same session key.
Why ECDHE Ensures Forward Secrecy?
Even if an attacker captures the encrypted communication and
later compromises the server's private key, they cannot decrypt past
communications. The ephemeral keys are destroyed after each session, so
the shared secret cannot be reconstructed.
Below is a Java example demonstrating ECDHE
(Elliptic Curve Diffie-Hellman Ephemeral) key exchange to compute the shared
secret. This can be integrated as part of your TLS handshake logic for
secure communication.
Java Code: ECDHE Key Exchange
java
import
javax.crypto.KeyAgreement; import
java.security.*; import
java.security.spec.ECGenParameterSpec; import
java.util.Base64; public class
ECDHEKeyExchange { public static void main(String[] args)
throws Exception { // Step 1: Generate key pairs for
Client and Server KeyPair clientKeyPair =
generateECKeyPair(); KeyPair serverKeyPair =
generateECKeyPair(); // Step 2: Compute shared secret on
the Client side byte[] clientSharedSecret =
generateSharedSecret( clientKeyPair.getPrivate(),
serverKeyPair.getPublic()); // Step 3: Compute shared secret on
the Server side byte[] serverSharedSecret =
generateSharedSecret( serverKeyPair.getPrivate(),
clientKeyPair.getPublic()); // Step 4: Verify both secrets are
the same System.out.println("Client
Shared Secret: " +
Base64.getEncoder().encodeToString(clientSharedSecret)); System.out.println("Server
Shared Secret: " +
Base64.getEncoder().encodeToString(serverSharedSecret)); if
(MessageDigest.isEqual(clientSharedSecret, serverSharedSecret)) { System.out.println("Key
Exchange Successful! Both sides share the same secret."); } else { System.out.println("Key
Exchange Failed! Secrets do not match."); } } // Generates an ECDH key pair using the
prime256v1 curve private static KeyPair
generateECKeyPair() throws Exception { KeyPairGenerator keyPairGenerator =
KeyPairGenerator.getInstance("EC"); ECGenParameterSpec ecSpec = new
ECGenParameterSpec("secp256r1"); // Also known as prime256v1 keyPairGenerator.initialize(ecSpec,
new SecureRandom()); return
keyPairGenerator.generateKeyPair(); } // Generates the shared secret using ECDH private static byte[]
generateSharedSecret(PrivateKey privateKey, PublicKey publicKey) throws
Exception { KeyAgreement keyAgreement =
KeyAgreement.getInstance("ECDH"); keyAgreement.init(privateKey); keyAgreement.doPhase(publicKey,
true); // Complete the key agreement phase return keyAgreement.generateSecret();
// Generate the shared secret } } |
Explanation
1. Key Generation (ECDHE)
Ø We
use secp256r1 (a widely used elliptic curve, also known as prime256v1)
for the key exchange.
Ø Both
the client and server generate ephemeral key pairs for each session.
2. Shared Secret Computation
Ø Both
the client and server compute a shared secret using:
ü
Client’s private key and Server’s
public key on the client side.
ü
Server’s private key and Client’s
public key on the server side.
Ø The generateSharedSecret()
method ensures both parties derive the same shared secret.
3. Key Agreement using KeyAgreement API
Ø KeyAgreement
is used to securely compute the shared secret with ECDHE.
4. Verify Key Exchange Success
Ø We
compare the shared secrets from both sides using MessageDigest.isEqual()
to ensure both are identical.
Sample Output
Plain text
Client Shared
Secret: 9YAdGgJkZd9yZqNyTW0d5Sbfi8XkG7HpTj8D2CJfSLk= Server Shared
Secret: 9YAdGgJkZd9yZqNyTW0d5Sbfi8XkG7HpTj8D2CJfSLk= Key Exchange
Successful! Both sides share the same secret. |
How This Fits into TLS 1.3 Handshake
Ø In TLS
1.3, the client and server exchange public keys (as part of the
Hello messages).
Ø Both
parties use ECDHE to derive a shared secret which, along with
random values, is used to generate the session key for encrypting data.
This code ensures forward secrecy—a critical feature
of TLS 1.3—because the key pairs are ephemeral, meaning they are generated per
session and discarded after use.
Here’s a Java implementation of HKDF (HMAC-based
Key Derivation Function) to derive a session key using the shared
secret along with the Client Random and Server Random values.
Dependencies
You need Bouncy Castle (a cryptographic library) for
HKDF. Add the following dependency to your Maven project:
Maven Dependency (pom.xml):
xml
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId> <version>1.70</version> </dependency> |
If you're not using Maven, download the Bouncy Castle JAR
from Bouncy Castle
and include it in your project.
Java Code for HKDF Session Key Derivation
java
import
org.bouncycastle.jcajce.provider.digest.SHA256; import
javax.crypto.Mac; import
javax.crypto.spec.SecretKeySpec; import
java.security.NoSuchAlgorithmException; import
java.security.InvalidKeyException; import
java.util.Arrays; public class
HKDFKeyDerivation { private static final String
HMAC_ALGORITHM = "HmacSHA256"; // HKDF uses HMAC-SHA-256 public static void main(String[] args)
throws Exception { // Example inputs byte[] sharedSecret =
"SharedSecretExample".getBytes(); // Replace with your ECDHE shared
secret byte[] clientRandom =
"ClientRandomValue".getBytes(); // Replace with actual client
random byte[] serverRandom =
"ServerRandomValue".getBytes(); // Replace with actual server
random // Step 1: Concatenate client and
server random byte[] salt =
concatenate(clientRandom, serverRandom); // Step 2: Perform HKDF extraction
and expansion byte[] sessionKey =
hkdfExtractAndExpand(sharedSecret, salt, 32); // 32-byte session key (256
bits) System.out.println("Derived
Session Key: " + bytesToHex(sessionKey)); } // Step 1: Concatenate client and server
random values private static byte[] concatenate(byte[]
array1, byte[] array2) { byte[] result = new
byte[array1.length + array2.length]; System.arraycopy(array1, 0, result,
0, array1.length); System.arraycopy(array2, 0, result,
array1.length, array2.length); return result; } // Step 2: HKDF extraction and expansion public static byte[]
hkdfExtractAndExpand(byte[] sharedSecret, byte[] salt, int keyLength) throws NoSuchAlgorithmException,
InvalidKeyException { // Perform HKDF-Extract using HMAC
with the shared secret and salt byte[] pseudoRandomKey =
hmacSHA256(salt, sharedSecret); // Perform HKDF-Expand to generate
the final session key return hkdfExpand(pseudoRandomKey,
keyLength); } // Helper method: HMAC-SHA256 computation private static byte[] hmacSHA256(byte[]
key, byte[] data) throws NoSuchAlgorithmException,
InvalidKeyException { Mac mac =
Mac.getInstance(HMAC_ALGORITHM); mac.init(new SecretKeySpec(key,
HMAC_ALGORITHM)); return mac.doFinal(data); } // Step 3: HKDF-Expand logic to derive
the final session key private static byte[] hkdfExpand(byte[]
prk, int outputLength) throws NoSuchAlgorithmException,
InvalidKeyException { int hashLen = 32; // Length of
HMAC-SHA256 output int n = (int) Math.ceil((double)
outputLength / hashLen); // Number of blocks required byte[] okm = new byte[outputLength];
// Output key material byte[] previousBlock = new byte[0]; for (int i = 0; i < n; i++) { Mac mac =
Mac.getInstance(HMAC_ALGORITHM); mac.init(new SecretKeySpec(prk,
HMAC_ALGORITHM)); mac.update(previousBlock); mac.update((byte) (i + 1)); //
Counter previousBlock = mac.doFinal(); System.arraycopy(previousBlock,
0, okm, i * hashLen, Math.min(hashLen, outputLength - (i * hashLen))); } return okm; } // Helper method: Convert byte array to
hex string private static String bytesToHex(byte[]
bytes) { StringBuilder sb = new
StringBuilder(); for (byte b : bytes) {
sb.append(String.format("%02x", b)); } return sb.toString(); } } |
Explanation
1. Input Parameters
Ø sharedSecret:
The secret derived from ECDHE key exchange.
Ø clientRandom:
Random bytes generated by the client during the TLS handshake.
Ø serverRandom:
Random bytes generated by the server during the TLS handshake.
2. HKDF Process
- Extract
Phase:
This step performs HMAC-SHA256 using the shared secret as input and the salt (client + server random) to generate a pseudo-random key (PRK). - Expand
Phase:
This phase uses the PRK to generate the required session key using iterative HMAC operations.
3. Running the Code
Ø The
code will print the derived session key in hexadecimal format.
Sample Output
Plain text
Derived
Session Key: 4f3e0d24f4c16b8a374a0ecadbba8e7d2e187b2463a5762342c21d5f95a3e9f7 |
How This Fits into TLS
Ø The session
key derived here can be used with AES-GCM encryption to securely
encrypt and decrypt communication between the client and server.
Ø This
ensures that the communication is confidential and tamper-proof
throughout the session.
This code provides a complete implementation of HKDF
to derive a session key using the shared secret and random values. You can
integrate it into your TLS handshake process for a Java-based secure
communication system.
Conclusion
TLS 1.2
Ø
In this illustration, we walked through the TLS
1.2 handshake process between the browser and the server. After the
handshake is complete, the communication between the client and server becomes
fully encrypted using AES-GCM. We also looked at how to configure Tomcat
to support only TLS 1.2 and how to validate the secure connection using Chrome,
Firefox, Postman, or curl.
TLS 1.3
Ø TLS
1.3 improves security and performance by reducing the handshake to one
round trip.
Ø The
use of ECDHE ensures forward secrecy, while AES-GCM
provides strong encryption.
Ø Tomcat
can be configured to enforce TLS 1.3 only, ensuring the highest level of
security.
Ø You
can verify the TLS 1.3 handshake using Google Chrome, Firefox, Postman, or
curl.
Ø The
generation of session keys in TLS 1.3 through ECDHE facilitates secure and
private communication. Both the client and server independently compute a
shared session key without transmitting it. This session key, in conjunction
with AES-GCM encryption, ensures the integrity and confidentiality of data
throughout the entire session.
This setup ensures that sensitive data, like employee
details, is transmitted securely over HTTPS.
To securely obtain employee information utilizing TLS 1.3 |
TLS 1.3 Demo
Click the button below to fetch data securely over TLS 1.3.
0 Comments