This guide explains the self-signed certificates used for secure communication between Linqra components.
For your convenience, all necessary certificates are pre-generated and available in the Linqra/keys folder. You can use these certificates directly for local development.

Pre-Generated Certificates

The following certificates and keystores are available in the Linqra/keys directory:
keys/
├── # Core Component Certificates
├── client-cert.pem                   # Client certificate
├── client-keystore.jks               # Client keystore
├── client-truststore.jks             # Client truststore

├── # Gateway Certificates
├── gateway-cert.pem                  # Gateway certificate (local)
├── gateway-keystore.jks              # Gateway keystore (local)
├── gateway-cert-container.pem        # Gateway certificate (container)
├── gateway-keystore-container.jks    # Gateway keystore (container)
├── gateway-truststore.jks            # Gateway truststore

├── # Eureka Discovery Certificates
├── eureka-cert.pem                  # Eureka certificate (local)
├── eureka-keystore.jks              # Eureka keystore (local)
├── eureka-cert-container.pem        # Eureka certificate (container)
├── eureka-keystore-container.jks    # Eureka keystore (container)
├── eureka-truststore.jks            # Eureka truststore

├── # Service-Specific Certificates
├── inventory-cert-container.pem      # Inventory service certificate
├── inventory-keystore-container.jks  # Inventory service keystore
├── product-cert-container.pem        # Product service certificate
└── product-keystore-container.jks    # Product service keystore
All certificates are configured with default password 123456 and are organized into:
  • Core client certificates for general use
  • Gateway certificates for both local and containerized environments
  • Eureka discovery certificates for both local and containerized environments
  • Service-specific certificates for containerized microservices

Certificate Generation

If you need to regenerate the certificates or understand how they were created, follow the instructions below.

Client Certificate

Generate a generic client certificate for your microservices:
# Generate client keystore
keytool -genkeypair -alias client-app -keyalg RSA -keysize 2048 \
  -keystore client-keystore.jks -validity 3650 -storetype PKCS12 \
  -dname "CN=localhost, OU=Software, O=Dipme, L=Richmond, ST=TX, C=US" \
  -storepass 123456 -keypass 123456

# Export client certificate
keytool -exportcert -alias client-app -file client-cert.pem \
  -keystore client-keystore.jks -storepass 123456

Gateway Certificates

Generate certificates for the API Gateway:
# For local development
keytool -genkeypair -alias gateway-app -keyalg RSA -keysize 2048 \
  -keystore gateway-keystore.jks -validity 3650 -storetype PKCS12 \
  -dname "CN=localhost, OU=Software, O=Dipme, L=Richmond, ST=TX, C=US" \
  -storepass 123456 -keypass 123456

keytool -exportcert -alias gateway-app -file gateway-cert.pem \
  -keystore gateway-keystore.jks -storepass 123456

# For containerized environment
keytool -genkeypair -alias gateway-app-container -keyalg RSA -keysize 2048 \
  -keystore gateway-keystore-container.jks -validity 3650 -storetype PKCS12 \
  -dname "CN=api-gateway-service, OU=Software, O=Dipme, L=Richmond, ST=TX, C=US" \
  -storepass 123456 -keypass 123456

keytool -exportcert -alias gateway-app-container -file gateway-cert-container.pem \
  -keystore gateway-keystore-container.jks -storepass 123456

Discovery Server Certificates

Generate certificates for the Eureka Discovery Server:
# For local development
keytool -genkeypair -alias eureka-app -keyalg RSA -keysize 2048 \
  -keystore eureka-keystore.jks -validity 3650 -storetype PKCS12 \
  -dname "CN=localhost, OU=Software, O=Dipme, L=Richmond, ST=TX, C=US" \
  -storepass 123456 -keypass 123456

keytool -exportcert -alias eureka-app -file eureka-cert.pem \
  -keystore eureka-keystore.jks -storepass 123456

# For containerized environment
keytool -genkeypair -alias eureka-app-container -keyalg RSA -keysize 2048 \
  -keystore eureka-keystore-container.jks -validity 3650 -storetype PKCS12 \
  -dname "CN=discovery-service, OU=Software, O=Dipme, L=Richmond, ST=TX, C=US" \
  -storepass 123456 -keypass 123456

keytool -exportcert -alias eureka-app-container -file eureka-cert-container.pem \
  -keystore eureka-keystore-container.jks -storepass 123456

Service-Specific Certificates

For containerized environments, generate certificates for each service:
# Inventory Service
keytool -genkeypair -alias inventory-service-container -keyalg RSA -keysize 2048 \
  -keystore inventory-service-keystore-container.jks -validity 3650 -storetype PKCS12 \
  -dname "CN=inventory-service, OU=Software, O=Dipme, L=Richmond, ST=TX, C=US" \
  -storepass 123456 -keypass 123456

keytool -exportcert -alias inventory-service-container \
  -file inventory-service-cert-container.pem \
  -keystore inventory-service-keystore-container.jks -storepass 123456

# Product Service
keytool -genkeypair -alias product-service-container -keyalg RSA -keysize 2048 \
  -keystore product-service-keystore-container.jks -validity 3650 -storetype PKCS12 \
  -dname "CN=product-service, OU=Software, O=Dipme, L=Richmond, ST=TX, C=US" \
  -storepass 123456 -keypass 123456

keytool -exportcert -alias product-service-container \
  -file product-service-cert-container.pem \
  -keystore product-service-keystore-container.jks -storepass 123456

# Quotes Service
keytool -genkeypair -alias quotes-service-container -keyalg RSA -keysize 2048 \
  -keystore quotes-service-keystore-container.jks -validity 3650 -storetype PKCS12 \
  -dname "CN=quotes-service, OU=Software, O=Dipme, L=Richmond, ST=TX, C=US" \
  -storepass 123456 -keypass 123456

keytool -exportcert -alias quotes-service-container \
  -file quotes-service-cert-container.pem \
  -keystore quotes-service-keystore-container.jks -storepass 123456  

# CounterApp Service
keytool -genkeypair -alias counter-app-container -keyalg RSA -keysize 2048 \
  -keystore counter-app-keystore-container.jks -validity 3650 -storetype PKCS12 \
  -dname "CN=counter-app, OU=Software, O=Dipme, L=Richmond, ST=TX, C=US" \
  -storepass 123456 -keypass 123456

keytool -exportcert -alias counter-app-container \
  -file counter-app-cert-container.pem \
  -keystore counter-app-keystore-container.jks -storepass 123456  

Truststore Configuration

Gateway Truststore

Import all certificates into the gateway truststore:
keytool -importcert -file gateway-cert.pem -alias gateway-app \
  -keystore gateway-truststore.jks -storepass 123456
keytool -importcert -file gateway-cert-container.pem -alias gateway-app-container \
  -keystore gateway-truststore.jks -storepass 123456
keytool -importcert -file client-cert.pem -alias client-app \
  -keystore gateway-truststore.jks -storepass 123456
keytool -importcert -file inventory-service-cert-container.pem -alias inventory-service-container \
  -keystore gateway-truststore.jks -storepass 123456
keytool -importcert -file product-service-cert-container.pem -alias product-service-container \
  -keystore gateway-truststore.jks -storepass 123456
keytool -importcert -file quotes-service-cert-container.pem -alias quotes-service-container \
  -keystore gateway-truststore.jks -storepass 123456  
keytool -importcert -file counter-app-cert-container.pem -alias counter-app-container \
  -keystore gateway-truststore.jks -storepass 123456

--Run this on the counter-app
keytool -import -alias localhost -file keys/certs/server-cert.pem -keystore /Users/mehmetsen/IdeaProjects/Linqra/keys/gateway-truststore.jks -storepass 123456 -noprompt


keytool -importcert -file eureka-cert.pem -alias eureka-app \
  -keystore gateway-truststore.jks -storepass 123456
keytool -importcert -file eureka-cert-container.pem -alias eureka-app-container \
  -keystore gateway-truststore.jks -storepass 123456

Client Truststore

Import all certificates into the client truststore:
keytool -importcert -file client-cert.pem -alias client-app \
  -keystore client-truststore.jks -storepass 123456
keytool -importcert -file inventory-service-cert-container.pem -alias inventory-service-container \
  -keystore client-truststore.jks -storepass 123456
keytool -importcert -file product-service-cert-container.pem -alias product-service-container \
  -keystore client-truststore.jks -storepass 123456
keytool -importcert -file quotes-service-cert-container.pem -alias quotes-service-container \
  -keystore client-truststore.jks -storepass 123456  
keytool -importcert -file counter-app-cert-container.pem -alias counter-app-container \
  -keystore client-truststore.jks -storepass 123456    
keytool -importcert -file gateway-cert.pem -alias gateway-app \
  -keystore client-truststore.jks -storepass 123456
keytool -importcert -file gateway-cert-container.pem -alias gateway-app-container \
  -keystore client-truststore.jks -storepass 123456
keytool -importcert -file eureka-cert.pem -alias eureka-app \
  -keystore client-truststore.jks -storepass 123456
keytool -importcert -file eureka-cert-container.pem -alias eureka-app-container \
  -keystore client-truststore.jks -storepass 123456

Eureka Truststore

Import all certificates into the Eureka truststore:
keytool -importcert -file gateway-cert.pem -alias gateway-app \
  -keystore eureka-truststore.jks -storepass 123456
keytool -importcert -file client-cert.pem -alias client-app \
  -keystore eureka-truststore.jks -storepass 123456
keytool -importcert -file inventory-cert-container.pem -alias inventory-service-container \
  -keystore eureka-truststore.jks -storepass 123456
keytool -importcert -file product-cert-container.pem -alias product-service-container \
  -keystore eureka-truststore.jks -storepass 123456
keytool -importcert -file quotes-service-cert-container.pem -alias quotes-service-container \
  -keystore eureka-truststore.jks -storepass 123456  
keytool -importcert -file counter-app-cert-container.pem -alias counter-app-container \
  -keystore eureka-truststore.jks -storepass 123456  
keytool -importcert -file gateway-cert-container.pem -alias gateway-app-container \
  -keystore eureka-truststore.jks -storepass 123456

Python Project Certificate Setup (CounterApp)

For Python projects like CounterApp that require mutual TLS (mTLS) authentication, you need to extract certificates from Java keystores and convert them to PEM format for use with Flask.

Prerequisites

Ensure you have the following files in your CounterApp/keys/ directory:
  • counter-app-keystore-container.jks (Java keystore)
  • client-truststore.jks (Java truststore)

Manual Certificate Extraction Process

If you need to manually extract certificates, follow these steps:

Step 1: Extract Certificate Aliases

# Get all certificate aliases from truststore
keytool -list -keystore keys/client-truststore.jks -storepass 123456 | grep "Alias name:"

Step 2: Extract Certificates from Truststore

# Create certs directory
mkdir -p keys/certs

# Extract each certificate (replace ALIAS_NAME with actual alias)
keytool -exportcert -alias ALIAS_NAME -file keys/certs/ALIAS_NAME.der \
  -keystore keys/client-truststore.jks -storepass 123456

Step 3: Convert DER to PEM Format

# Convert each DER certificate to PEM
openssl x509 -inform DER -in keys/certs/ALIAS_NAME.der -out keys/certs/ALIAS_NAME.pem

Step 4: Extract Server Certificate and Key

# Extract server certificate
keytool -exportcert -alias counter-app-container -file keys/certs/server-cert.der \
  -keystore keys/counter-app-keystore-container.jks -storepass 123456

# Convert server certificate to PEM
openssl x509 -inform DER -in keys/certs/server-cert.der -out keys/certs/server-cert.pem

# Extract server private key (requires keytool with -importkeystore)
keytool -importkeystore -srckeystore keys/counter-app-keystore-container.jks \
  -destkeystore keys/certs/server.p12 -deststoretype PKCS12 \
  -srcalias counter-app-container -deststorepass 123456 -srcstorepass 123456

# Extract private key from PKCS12
openssl pkcs12 -in keys/certs/server.p12 -out keys/certs/server-key.pem -nocerts -nodes -passin pass:123456

Step 5: Create CA Bundle

# Combine all certificates into CA bundle
cat keys/certs/*.pem > keys/certs/ca-bundle.pem

Step 6: Create CA Certificate for Client Signing

# Generate CA private key
openssl genrsa -out keys/certs/ca-key.pem 2048

# Generate CA certificate
openssl req -new -x509 -key keys/certs/ca-key.pem -out keys/certs/ca-cert.pem \
  -days 3650 -subj "/CN=counter-app-ca/OU=Software/O=Dipme/L=Richmond/ST=TX/C=US"

Step 7: Create Client Certificate

# Generate client private key
openssl genrsa -out keys/certs/client-key.pem 2048

# Create client certificate signing request
openssl req -new -key keys/certs/client-key.pem -out keys/certs/client-cert.csr \
  -subj "/CN=client-app/OU=Software/O=Dipme/L=Richmond/ST=TX/C=US"

# Sign client certificate with CA
openssl x509 -req -in keys/certs/client-cert.csr -CA keys/certs/ca-cert.pem \
  -CAkey keys/certs/ca-key.pem -CAcreateserial -out keys/certs/client-cert.pem -days 365

Step 8: Update CA Bundle

# Add CA certificate to bundle
cat keys/certs/ca-cert.pem >> keys/certs/ca-bundle.pem

Step 9: Validate CA Bundle

# Verify CA certificate is properly included in the bundle
openssl x509 -in keys/certs/ca-bundle.pem -text -noout | grep -A 3 "Subject:" | grep "app-ca"

# Show all certificates in the CA bundle
openssl x509 -in keys/certs/ca-bundle.pem -text -noout | grep -A 2 "Subject:"

Run Complete Certificate Setup Script

python generate_all_certs.py
This script automatically handles ALL certificate setup parts:
  • 1: Get certificate aliases dynamically from truststore
  • 2: Extract all certificates from truststore (DER format)
  • 3: Convert DER certificates to PEM format
  • 4: Extract server certificate and private key from Java keystore
  • 5: Extract server private key from Java keystore
  • 6: Create CA bundle with all certificates
  • 7: Clean up temporary files and unnecessary certificates
  • 8: Create CA certificate for signing client certificates
  • 9: Create client certificate signed by the CA
  • 10: Update CA bundle with the CA certificate and cleanup
Final files after script execution:
  • server-cert.pem: Server certificate (for Flask HTTPS)
  • server-key.pem: Server private key (for Flask HTTPS)
  • ca-bundle.pem: Combined CA certificates (for server validation)
  • ca-key.pem: CA private key
  • ca-cert.pem: CA certificate
  • client-key.pem: Client private key
  • client-cert.pem: Client certificate
Note: The script is completely dynamic and will automatically detect and process all certificates in your truststore. All manual steps are now automated!

Part 3: Import Client Certificate for Browser Testing

Step 5a: Import Certificate into macOS Keychain
# Import certificate into macOS Keychain for Chrome
security import keys/certs/client-cert.pem -k ~/Library/Keychains/login.keychain-db \
  -T /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome -f pemseq

# Import private key into macOS Keychain
security import keys/certs/client-key.pem -k ~/Library/Keychains/login.keychain-db \
  -T /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome -t priv
Alternative: Import via Keychain Access GUI (Recommended)
  1. Open Keychain Access application
  2. Go to File → Import Items…
  3. Select keys/certs/client-cert.pem and keys/certs/client-key.pem files
  4. Enter your macOS password when prompted
  5. Set trust settings to “Always Trust” for testing
Start Flask App with mTLS Enabled This step starts the Flask application with mutual TLS enabled.
export EUREKA_ENABLED=false && export MUTUAL_TLS_ENABLED=true && export HTTP_ENABLED=false && python app.py

Testing mTLS

Test with curl (should succeed):
curl -vk --cert keys/certs/client-cert.pem --key keys/certs/client-key.pem https://127.0.0.1:5001/health
Test without certificate (should fail):
curl -vk https://127.0.0.1:5001/health
Test in browser:
  • Open https://127.0.0.1:5001/health in Chrome
  • Chrome will prompt for certificate selection
  • Select the “client-app” certificate
  • Enter your macOS password when prompted

File Structure After Setup

CounterApp/keys/
├── counter-app-keystore-container.jks    # Java keystore (from Phase 1)
├── client-truststore.jks                 # Java truststore (from Phase 1)
└── certs/
    ├── server-cert.pem                  # Server certificate (for Flask HTTPS)
    ├── server-key.pem                   # Server private key (for Flask HTTPS)
    ├── ca-key.pem                       # CA private key
    ├── ca-cert.pem                      # CA certificate
    ├── client-key.pem                   # Client private key
    ├── client-cert.pem                  # Client certificate
    ├── client-cert.csr                  # Client certificate signing request
    ├── ca-bundle.pem                    # Combined CA certificates
    └── ... (other extracted certificates)

Verification

To verify the contents of any truststore:
keytool -list -v -keystore <truststore-name>.jks -storepass 123456
Replace <truststore-name> with either gateway-truststore, client-truststore, or eureka-truststore.

Edge Service SSL Configuration

For secure local development of the Edge Service, you’ll need to set up additional SSL certificates. These certificates enable HTTPS access through https://localhost:3000.

Generate Edge Service Certificate

Navigate to the keys directory and generate the required certificate:
# Navigate to keys directory
cd keys

# Generate certificate and private key
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
    -keyout edge-private.key \
    -out edge-certificate.crt \
    -subj "/C=US/ST=Texas/L=Houston/O=Development/OU=IT/CN=localhost"

Trust the Certificate

sudo security add-trusted-cert -d -r trustRoot \
    -k /Library/Keychains/System.keychain edge-certificate.crt

Security Best Practices

Never commit private keys or certificates to version control. These files should be generated locally and kept secure.
Add the following to your .gitignore file:
# SSL/TLS Certificates
keys/*.key
keys/*.crt
The generated certificates are valid for 365 days. For production environments, always use proper CA-signed certificates.

Certificate Details

The Edge Service certificate is configured with the following properties:
  • Validity: 365 days
  • Key Type: RSA 2048-bit
  • Common Name (CN): localhost
  • Organization Unit (OU): IT
  • Organization (O): Development
  • Location (L): Houston
  • State (ST): Texas
  • Country (C): US

Directory Structure

After generating the Edge Service certificates, your keys directory will include:
keys/
├── # Existing certificates ...
├── edge-certificate.crt          # Edge Service certificate
└── edge-private.key             # Edge Service private key
Ensure proper file permissions are set on the private key:
  • Linux/macOS: chmod 600 edge-private.key
  • Windows: Restrict access through file properties