KeyStore and TrustStore are fundamental components of Java's security infrastructure for managing cryptographic keys and certificates. They play crucial roles in SSL/TLS connections, encryption, and digital signatures.
Basic Concepts and Setup
1. Understanding KeyStore vs TrustStore
public class SecurityConcepts {
public void explainKeyStores() {
System.out.println("=== KeyStore vs TrustStore ===");
System.out.println("\nKeyStore (Client/Server Identity):");
System.out.println("- Contains private keys and certificates");
System.out.println("- Proves identity to other parties");
System.out.println("- Used in SSL/TLS for client authentication");
System.out.println("- Typically password-protected");
System.out.println("\nTrustStore (Trusted Parties):");
System.out.println("- Contains trusted CA certificates");
System.out.println("- Validates other parties' identities");
System.out.println("- Used in SSL/TLS for server authentication");
System.out.println("- May not be password-protected");
System.out.println("\nDefault Locations:");
System.out.println("- KeyStore: $JAVA_HOME/lib/security/cacerts");
System.out.println("- TrustStore: $JAVA_HOME/lib/security/cacerts");
}
public void commonStoreTypes() {
System.out.println("\n=== Common Store Types ===");
System.out.println("JKS - Java KeyStore (Java specific)");
System.out.println("PKCS12 - Standard format (recommended)");
System.out.println("JCEKS - More secure JKS variant");
}
}
2. System Properties Configuration
public class SecuritySystemProperties {
public static void configureSSLProperties() {
// KeyStore configuration (our identity)
System.setProperty("javax.net.ssl.keyStore", "/path/to/keystore.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "keystorepassword");
System.setProperty("javax.net.ssl.keyStoreType", "JKS");
// TrustStore configuration (who we trust)
System.setProperty("javax.net.ssl.trustStore", "/path/to/truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "truststorepassword");
System.setProperty("javax.net.ssl.trustStoreType", "JKS");
// Additional SSL properties
System.setProperty("jdk.tls.client.protocols", "TLSv1.2,TLSv1.3");
System.setProperty("https.protocols", "TLSv1.2,TLSv1.3");
}
public static void configureForClientAuth() {
// Enable client authentication
System.setProperty("javax.net.ssl.keyStore", "/path/to/client-keystore.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "clientpassword");
// Trust the server's CA
System.setProperty("javax.net.ssl.trustStore", "/path/to/client-truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "trustpassword");
}
}
KeyStore Management
3. Basic KeyStore Operations
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
public class KeyStoreManager {
private final KeyStore keyStore;
private final String keyStorePath;
private final char[] keyStorePassword;
public KeyStoreManager(String keyStorePath, char[] keyStorePassword, String keyStoreType)
throws Exception {
this.keyStorePath = keyStorePath;
this.keyStorePassword = keyStorePassword;
this.keyStore = KeyStore.getInstance(keyStoreType);
loadKeyStore();
}
private void loadKeyStore() throws Exception {
try (FileInputStream fis = new FileInputStream(keyStorePath)) {
keyStore.load(fis, keyStorePassword);
} catch (Exception e) {
// If keystore doesn't exist, create empty one
System.out.println("Creating new keystore: " + keyStorePath);
keyStore.load(null, keyStorePassword);
}
}
public void saveKeyStore() throws Exception {
try (FileOutputStream fos = new FileOutputStream(keyStorePath)) {
keyStore.store(fos, keyStorePassword);
}
}
// Add a private key entry
public void addPrivateKeyEntry(String alias, PrivateKey privateKey, Certificate[] chain,
char[] keyPassword) throws Exception {
keyStore.setKeyEntry(alias, privateKey, keyPassword, chain);
saveKeyStore();
System.out.println("Private key added with alias: " + alias);
}
// Add a trusted certificate
public void addTrustedCertificate(String alias, Certificate cert) throws Exception {
keyStore.setCertificateEntry(alias, cert);
saveKeyStore();
System.out.println("Trusted certificate added with alias: " + alias);
}
// Get a private key
public PrivateKey getPrivateKey(String alias, char[] keyPassword) throws Exception {
Key key = keyStore.getKey(alias, keyPassword);
if (key instanceof PrivateKey) {
return (PrivateKey) key;
}
throw new KeyStoreException("No private key found for alias: " + alias);
}
// Get certificate chain
public Certificate[] getCertificateChain(String alias) throws Exception {
return keyStore.getCertificateChain(alias);
}
// Get a certificate
public Certificate getCertificate(String alias) throws Exception {
return keyStore.getCertificate(alias);
}
// Check if alias exists
public boolean containsAlias(String alias) throws Exception {
return keyStore.containsAlias(alias);
}
// List all entries
public void listEntries() throws Exception {
System.out.println("=== KeyStore Entries ===");
Enumeration<String> aliases = keyStore.aliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
System.out.println("Alias: " + alias);
System.out.println(" Type: " +
(keyStore.isKeyEntry(alias) ? "Private Key Entry" : "Trusted Certificate"));
if (keyStore.isCertificateEntry(alias)) {
Certificate cert = keyStore.getCertificate(alias);
if (cert instanceof X509Certificate) {
X509Certificate x509 = (X509Certificate) cert;
System.out.println(" Subject: " + x509.getSubjectX500Principal());
System.out.println(" Issuer: " + x509.getIssuerX500Principal());
System.out.println(" Expires: " + x509.getNotAfter());
}
}
}
}
// Delete an entry
public void deleteEntry(String alias) throws Exception {
if (keyStore.containsAlias(alias)) {
keyStore.deleteEntry(alias);
saveKeyStore();
System.out.println("Deleted entry: " + alias);
} else {
System.out.println("Alias not found: " + alias);
}
}
// Change key password
public void changeKeyPassword(String alias, char[] oldPassword, char[] newPassword)
throws Exception {
Key key = keyStore.getKey(alias, oldPassword);
Certificate[] chain = keyStore.getCertificateChain(alias);
keyStore.setKeyEntry(alias, key, newPassword, chain);
saveKeyStore();
System.out.println("Password changed for alias: " + alias);
}
}
4. KeyStore Creation and Certificate Generation
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.math.BigInteger;
import java.util.Date;
public class KeyStoreGenerator {
// Create a new KeyStore with a self-signed certificate
public static void createKeyStoreWithSelfSignedCert(String keyStorePath,
String keyStorePassword,
String keyPassword,
String alias,
String commonName,
String organization) throws Exception {
// Generate key pair
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
KeyPair keyPair = keyGen.generateKeyPair();
// Create self-signed certificate
X509Certificate cert = generateSelfSignedCertificate(keyPair, commonName, organization);
// Create KeyStore and add the key entry
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(null, keyStorePassword.toCharArray());
Certificate[] chain = {cert};
keyStore.setKeyEntry(alias, keyPair.getPrivate(), keyPassword.toCharArray(), chain);
// Save KeyStore
try (FileOutputStream fos = new FileOutputStream(keyStorePath)) {
keyStore.store(fos, keyStorePassword.toCharArray());
}
System.out.println("KeyStore created: " + keyStorePath);
System.out.println("Alias: " + alias);
System.out.println("Certificate Subject: " + cert.getSubjectX500Principal());
}
private static X509Certificate generateSelfSignedCertificate(KeyPair keyPair,
String commonName,
String organization) throws Exception {
// This is a simplified version - in production, use proper certificate generation
// For real certificates, use libraries like BouncyCastle or proper CA
String subject = "CN=" + commonName + ", O=" + organization;
String issuer = subject; // Self-signed
// Note: Actual certificate generation requires more complex code
// This is a placeholder for the concept
// In practice, you would use:
// CertificateFactory, X509V3CertificateGenerator, or proper CA services
return null; // Implementation would go here
}
// Import a certificate into TrustStore
public static void importCertificateToTrustStore(String trustStorePath,
String trustStorePassword,
String alias,
String certPath) throws Exception {
// Load the certificate
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate cert;
try (FileInputStream certStream = new FileInputStream(certPath)) {
cert = cf.generateCertificate(certStream);
}
// Load or create TrustStore
KeyStore trustStore = KeyStore.getInstance("JKS");
File trustStoreFile = new File(trustStorePath);
if (trustStoreFile.exists()) {
try (FileInputStream fis = new FileInputStream(trustStoreFile)) {
trustStore.load(fis, trustStorePassword.toCharArray());
}
} else {
trustStore.load(null, trustStorePassword.toCharArray());
}
// Add certificate to TrustStore
trustStore.setCertificateEntry(alias, cert);
// Save TrustStore
try (FileOutputStream fos = new FileOutputStream(trustStorePath)) {
trustStore.store(fos, trustStorePassword.toCharArray());
}
System.out.println("Certificate imported to TrustStore: " + trustStorePath);
System.out.println("Alias: " + alias);
}
}
SSL/TLS Configuration with KeyStore and TrustStore
5. SSL Context Configuration
import javax.net.ssl.*;
import java.security.KeyStore;
public class SSLContextFactory {
// Create SSLContext for server with KeyStore
public static SSLContext createServerSSLContext(String keyStorePath,
String keyStorePassword,
String keyPassword) throws Exception {
// Load KeyStore
KeyStore keyStore = KeyStore.getInstance("PKCS12");
try (FileInputStream fis = new FileInputStream(keyStorePath)) {
keyStore.load(fis, keyStorePassword.toCharArray());
}
// Set up KeyManager
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, keyPassword.toCharArray());
// Create SSLContext
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), null, new SecureRandom());
return sslContext;
}
// Create SSLContext for client with TrustStore
public static SSLContext createClientSSLContext(String trustStorePath,
String trustStorePassword) throws Exception {
// Load TrustStore
KeyStore trustStore = KeyStore.getInstance("JKS");
try (FileInputStream fis = new FileInputStream(trustStorePath)) {
trustStore.load(fis, trustStorePassword.toCharArray());
}
// Set up TrustManager
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
// Create SSLContext
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());
return sslContext;
}
// Create SSLContext with both KeyStore and TrustStore
public static SSLContext createMutualAuthSSLContext(String keyStorePath,
String keyStorePassword,
String keyPassword,
String trustStorePath,
String trustStorePassword) throws Exception {
// Load KeyStore
KeyStore keyStore = KeyStore.getInstance("PKCS12");
try (FileInputStream fis = new FileInputStream(keyStorePath)) {
keyStore.load(fis, keyStorePassword.toCharArray());
}
// Load TrustStore
KeyStore trustStore = KeyStore.getInstance("JKS");
try (FileInputStream fis = new FileInputStream(trustStorePath)) {
trustStore.load(fis, trustStorePassword.toCharArray());
}
// Set up KeyManager
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, keyPassword.toCharArray());
// Set up TrustManager
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
// Create SSLContext
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
return sslContext;
}
// Create SSLServerSocketFactory for server
public static SSLServerSocketFactory createSSLServerSocketFactory(SSLContext sslContext) {
return sslContext.getServerSocketFactory();
}
// Create SSLSocketFactory for client
public static SSLSocketFactory createSSLSocketFactory(SSLContext sslContext) {
return sslContext.getSocketFactory();
}
}
6. HTTPS Client with Custom TrustStore
import javax.net.ssl.*;
import java.security.cert.X509Certificate;
public class CustomHttpsClient {
private final SSLContext sslContext;
public CustomHttpsClient(String trustStorePath, String trustStorePassword) throws Exception {
this.sslContext = SSLContextFactory.createClientSSLContext(trustStorePath, trustStorePassword);
}
public CustomHttpsClient(String keyStorePath, String keyStorePassword, String keyPassword,
String trustStorePath, String trustStorePassword) throws Exception {
this.sslContext = SSLContextFactory.createMutualAuthSSLContext(
keyStorePath, keyStorePassword, keyPassword, trustStorePath, trustStorePassword);
}
// Create HTTP client with custom SSL context
public CloseableHttpClient createHttpClient() {
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
sslContext,
new String[]{"TLSv1.2", "TLSv1.3"},
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier()
);
return HttpClients.custom()
.setSSLSocketFactory(sslSocketFactory)
.build();
}
// Make HTTPS request
public String makeHttpsRequest(String url) throws Exception {
try (CloseableHttpClient httpClient = createHttpClient();
CloseableHttpResponse response = httpClient.execute(new HttpGet(url))) {
return EntityUtils.toString(response.getEntity());
}
}
// Create trusting all client (DANGEROUS - for testing only)
public static CloseableHttpClient createTrustAllClient() throws Exception {
// Create trust manager that trusts all certificates
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
// Trust all
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
// Trust all
}
}
};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, new SecureRandom());
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
sslContext,
NoopHostnameVerifier.INSTANCE
);
return HttpClients.custom()
.setSSLSocketFactory(sslSocketFactory)
.build();
}
}
Spring Boot Configuration
7. Spring Boot SSL Configuration
@Configuration
public class SpringBootSSLConfig {
@Bean
@ConfigurationProperties(prefix = "server.ssl")
public SslBundle sslBundle() {
return SslBundle.of(getKeyStore(), getTrustStore());
}
@Bean
public KeyStore keyStore() throws Exception {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
try (InputStream is = new FileInputStream("classpath:keystore.p12")) {
keyStore.load(is, "password".toCharArray());
}
return keyStore;
}
@Bean
public KeyStore trustStore() throws Exception {
KeyStore trustStore = KeyStore.getInstance("JKS");
try (InputStream is = new FileInputStream("classpath:truststore.jks")) {
trustStore.load(is, "trustpassword".toCharArray());
}
return trustStore;
}
}
// application.yml configuration
/*
server:
ssl:
key-store: classpath:keystore.p12
key-store-password: password
key-store-type: PKCS12
key-alias: myserver
key-password: keypassword
trust-store: classpath:truststore.jks
trust-store-password: trustpassword
trust-store-type: JKS
port: 8443
# For client certificate authentication
server:
ssl:
client-auth: need
*/
@RestController
public class SecureController {
@GetMapping("/secure")
public String secureEndpoint() {
return "This is a secure endpoint";
}
@GetMapping("/client-cert")
public String clientCertEndpoint(@AuthenticationPrincipal X509Certificate clientCert) {
String subject = clientCert.getSubjectX500Principal().getName();
return "Hello client with certificate: " + subject;
}
}
8. Spring RestTemplate with SSL
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate sslRestTemplate() throws Exception {
SSLContext sslContext = SSLContextFactory.createClientSSLContext(
"truststore.jks", "trustpassword");
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
sslContext,
new String[]{"TLSv1.2", "TLSv1.3"},
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier()
);
HttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(socketFactory)
.build();
HttpComponentsClientHttpRequestFactory factory =
new HttpComponentsClientHttpRequestFactory(httpClient);
return new RestTemplate(factory);
}
@Bean
public RestTemplate mutualAuthRestTemplate() throws Exception {
SSLContext sslContext = SSLContextFactory.createMutualAuthSSLContext(
"client-keystore.p12", "clientpassword", "keypassword",
"client-truststore.jks", "trustpassword");
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
sslContext,
new String[]{"TLSv1.2", "TLSv1.3"},
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier()
);
HttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(socketFactory)
.build();
HttpComponentsClientHttpRequestFactory factory =
new HttpComponentsClientHttpRequestFactory(httpClient);
return new RestTemplate(factory);
}
}
@Service
public class SecureApiClient {
private final RestTemplate sslRestTemplate;
private final RestTemplate mutualAuthRestTemplate;
public SecureApiClient(@Qualifier("sslRestTemplate") RestTemplate sslRestTemplate,
@Qualifier("mutualAuthRestTemplate") RestTemplate mutualAuthRestTemplate) {
this.sslRestTemplate = sslRestTemplate;
this.mutualAuthRestTemplate = mutualAuthRestTemplate;
}
public String callSecureApi(String url) {
return sslRestTemplate.getForObject(url, String.class);
}
public String callMutualAuthApi(String url) {
return mutualAuthRestTemplate.getForObject(url, String.class);
}
}
Advanced Usage Patterns
9. Dynamic Trust Management
public class DynamicTrustManager implements X509TrustManager {
private final X509TrustManager defaultTrustManager;
private final Set<X509Certificate> additionalTrustedCerts;
public DynamicTrustManager(KeyStore trustStore) throws Exception {
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
this.defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0];
this.additionalTrustedCerts = new HashSet<>();
}
public void addTrustedCertificate(X509Certificate cert) {
additionalTrustedCerts.add(cert);
}
public void removeTrustedCertificate(X509Certificate cert) {
additionalTrustedCerts.remove(cert);
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
try {
defaultTrustManager.checkClientTrusted(chain, authType);
} catch (CertificateException e) {
// Check if any certificate in the chain is in our additional trusted set
if (!isChainTrusted(chain)) {
throw e;
}
}
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
try {
defaultTrustManager.checkServerTrusted(chain, authType);
} catch (CertificateException e) {
// Check if any certificate in the chain is in our additional trusted set
if (!isChainTrusted(chain)) {
throw e;
}
}
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return defaultTrustManager.getAcceptedIssuers();
}
private boolean isChainTrusted(X509Certificate[] chain) {
for (X509Certificate cert : chain) {
if (additionalTrustedCerts.contains(cert)) {
return true;
}
}
return false;
}
}
10. Certificate Validation and Verification
public class CertificateValidator {
public static boolean validateCertificateChain(X509Certificate[] chain) {
if (chain == null || chain.length == 0) {
return false;
}
try {
// Validate from leaf to root
for (int i = 0; i < chain.length; i++) {
X509Certificate cert = chain[i];
// Check validity period
cert.checkValidity();
// Verify signature (except for root CA)
if (i > 0) {
cert.verify(chain[i-1].getPublicKey());
}
}
return true;
} catch (Exception e) {
System.err.println("Certificate validation failed: " + e.getMessage());
return false;
}
}
public static void printCertificateInfo(X509Certificate cert) {
System.out.println("=== Certificate Information ===");
System.out.println("Subject: " + cert.getSubjectX500Principal());
System.out.println("Issuer: " + cert.getIssuerX500Principal());
System.out.println("Serial Number: " + cert.getSerialNumber());
System.out.println("Valid From: " + cert.getNotBefore());
System.out.println("Valid Until: " + cert.getNotAfter());
System.out.println("Signature Algorithm: " + cert.getSigAlgName());
System.out.println("Public Key Algorithm: " + cert.getPublicKey().getAlgorithm());
}
public static boolean isCertificateExpiringSoon(X509Certificate cert, int daysThreshold) {
Date now = new Date();
Date thresholdDate = new Date(now.getTime() + daysThreshold * 24 * 60 * 60 * 1000L);
return cert.getNotAfter().before(thresholdDate);
}
}
Best Practices and Security Considerations
11. Security Best Practices
public class SecurityBestPractices {
public static void demonstrateBestPractices() {
System.out.println("=== KeyStore Security Best Practices ===");
System.out.println("\n1. Store Configuration:");
System.out.println(" • Use strong passwords for KeyStore and private keys");
System.out.println(" • Store passwords securely (not in source code)");
System.out.println(" • Use environment variables or secure config servers");
System.out.println(" • Restrict file permissions on KeyStore files");
System.out.println("\n2. Certificate Management:");
System.out.println(" • Use PKCS12 format instead of JKS for new applications");
System.out.println(" • Regularly rotate certificates and keys");
System.out.println(" • Monitor certificate expiration dates");
System.out.println(" • Use proper CA-signed certificates in production");
System.out.println("\n3. SSL/TLS Configuration:");
System.out.println(" • Use TLS 1.2 or higher");
System.out.println(" • Disable weak ciphers");
System.out.println(" • Implement proper certificate pinning");
System.out.println(" • Use mutual TLS for sensitive APIs");
System.out.println("\n4. Code Security:");
System.out.println(" • Clear password arrays after use");
System.out.println(" • Use try-with-resources for streams");
System.out.println(" • Validate certificate chains");
System.out.println(" • Implement proper error handling");
}
// Secure password handling
public static class SecurePasswordHandler {
public static char[] getPasswordFromEnv(String envVar) {
String password = System.getenv(envVar);
if (password == null) {
throw new IllegalStateException("Environment variable not found: " + envVar);
}
return password.toCharArray();
}
public static void clearPassword(char[] password) {
if (password != null) {
Arrays.fill(password, '\0');
}
}
public static void clearPassword(byte[] password) {
if (password != null) {
Arrays.fill(password, (byte) 0);
}
}
}
// Secure KeyStore usage pattern
public static void secureKeyStoreUsage() throws Exception {
char[] keyStorePassword = SecurePasswordHandler.getPasswordFromEnv("KEYSTORE_PASSWORD");
char[] keyPassword = SecurePasswordHandler.getPasswordFromEnv("KEY_PASSWORD");
try {
KeyStoreManager manager = new KeyStoreManager("keystore.p12", keyStorePassword, "PKCS12");
// Use the KeyStore...
} finally {
// Clear sensitive data from memory
SecurePasswordHandler.clearPassword(keyStorePassword);
SecurePasswordHandler.clearPassword(keyPassword);
}
}
}
Testing and Debugging
12. Testing SSL Connections
public class SSLConnectionTester {
public static void testSSLConnection(String url) {
try {
// Enable SSL debugging
System.setProperty("javax.net.debug", "ssl:handshake");
URL httpsUrl = new URL(url);
HttpsURLConnection connection = (HttpsURLConnection) httpsUrl.openConnection();
// Set up hostname verifier
connection.setHostnameVerifier((hostname, session) -> {
System.out.println("Verifying hostname: " + hostname);
return true; // In production, use proper verification
});
// Get response
int responseCode = connection.getResponseCode();
System.out.println("Response Code: " + responseCode);
// Print SSL session info
SSLSession session = connection.getSSLSession();
System.out.println("Cipher Suite: " + session.getCipherSuite());
System.out.println("Protocol: " + session.getProtocol());
} catch (Exception e) {
System.err.println("SSL connection test failed: " + e.getMessage());
e.printStackTrace();
}
}
public static void listSupportedCiphers() {
try {
SSLContext context = SSLContext.getDefault();
SSLSocketFactory factory = context.getSocketFactory();
String[] defaultCiphers = factory.getDefaultCipherSuites();
String[] supportedCiphers = factory.getSupportedCipherSuites();
System.out.println("=== Supported Cipher Suites ===");
for (String cipher : supportedCiphers) {
System.out.println(cipher);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Key Takeaways:
- KeyStore stores your private keys and certificates (your identity)
- TrustStore stores trusted CA certificates (who you trust)
- PKCS12 is the recommended format for new applications
- Always secure passwords and never hardcode them
- Use proper SSL/TLS configurations with strong protocols and ciphers
- Implement proper certificate validation and monitoring
- Consider mutual TLS for sensitive applications
- Regularly rotate certificates and monitor expiration
KeyStore and TrustStore are essential for secure Java applications, enabling SSL/TLS encryption, client authentication, and secure communication in enterprise environments.