Manage Java Certificates with Keytool
Launch a Windows EC2 instance, break Java's certificate trust, then diagnose and repair it with keytool.
Introduction
30 Second Summary
Your teammate pings you at 9am: "The Java app stopped connecting to our payment provider overnight." You check the logs and see an SSL handshake failure. The fix lives in one file you've never touched before: the certificates truststore.
In this project, you will launch a Windows EC2 instance, install Java, deliberately break the certificate trust chain, and then diagnose and repair it using keytool. You'll walk away with proven, hands-on experience managing Java certificates on a real server.
What You'll Build
A Java HTTPS connection that breaks, gets diagnosed with keytool, and comes back to life after you import the missing certificate — all on a live cloud server you built from scratch.
By the end of this project, you'll have:
- Launched a Windows EC2 instance, installed Java from scratch, and confirmed keytool works on the remote server.
- Ran a Java program that makes a successful HTTPS call, then deliberately broke the trust chain and watched it fail with an SSL exception.
- Diagnosed the failure using keytool inspection commands, imported the missing root certificate, and proved the connection works again.
- Secret Mission: Migrated certificates between PKCS12 and JKS keystore formats using -importkeystore.
Are there any prerequisites?
You need an AWS account (free tier eligible) and basic familiarity with the Windows command line. No prior Java programming or certificate management experience is needed.
Launch and Connect to a Windows EC2 Instance
To demonstrate certificate management on a real server, you need an actual server. A local machine works, but an EC2 instance proves you can operate in a cloud environment where production Java apps actually run.
In this step, you will launch a Windows Server instance on AWS, configure network access for Remote Desktop, and connect to it.
In this step, get ready to:
- Launch a Windows Server EC2 instance with RDP access.
- Connect to the instance using Remote Desktop.
- Open Command Prompt on the remote server.
Launch a Windows Server instance
- Sign in to the AWS Management Console at https://console.aws.amazon.com.
- In the top navigation bar, make sure your region is set to us-east-1 (N. Virginia).
- Type EC2 in the search bar and select EC2 from the results.
- Click Launch instance.
- Under Name and tags, enter JavaCertLab.
- Under Application and OS Images, click Windows.
- Select the Microsoft Windows Server 2022 Base AMI (Free tier eligible).
- Under Instance type, select t2.micro (Free tier eligible).
Configure the key pair and security group
- Under Key pair (login), click Create new key pair.
- Enter java-cert-lab as the key pair name.
- Leave the type as RSA and format as .pem.
- Click Create key pair. The file downloads automatically. Save it somewhere safe.
- Under Network settings, click Edit.
- Under Inbound security group rules, confirm that an RDP rule exists with Type set to RDP and Source set to My IP.
- Click Launch instance.
Wait for the instance state to show Running and the status check to show 2/2 checks passed. This takes 2-4 minutes for Windows instances.
Connect via Remote Desktop
- Select your JavaCertLab instance in the EC2 console.
- Click Connect.
- Select the RDP client tab.
- Click Get password.
- Click Upload private key file and select the java-cert-lab.pem file you downloaded.
- Click Decrypt password. Copy the password that appears.
- Click Download remote desktop file and open it.
- When prompted for credentials, enter Administrator as the username and paste the decrypted password.
- Click Yes to accept the certificate warning.
You should see the Windows Server desktop. You are now connected to your remote instance.
RDP connection refused?
- Make sure the instance status shows 2/2 checks passed. Windows takes longer to boot than Linux.
- Check that your security group allows RDP (port 3389) from your IP address.
- If your IP changed since launch, update the security group inbound rule with your current IP.
Help me connect to my Windows EC2 instance via RDP.
- On the Windows Server desktop, press the Windows key to open the search bar.
- Type cmd and press Enter to open Command Prompt.
Your cloud server is live and ready. Next up, you will install Java and get your first look at the truststore.
Install Java and Verify Your Truststore
Your EC2 instance is live and you have a Command Prompt open. Now you need the tool that manages Java certificates: keytool. It ships with every JDK installation.
In this step, you will install the JDK on your Windows Server, locate the cacerts truststore, and take your first look inside it.
In this step, get ready to:
- Install JDK 21 on the Windows Server instance.
- Locate and back up the cacerts truststore file.
- List the trusted certificates to confirm keytool works.
Download and install JDK 21
A fresh Windows Server instance does not have Java installed. You will install Adoptium's Temurin JDK 21, a widely-used open source distribution.
- On the EC2 instance, open Server Manager (it launches automatically on login).
- Click Local Server in the left sidebar.
- Find IE Enhanced Security Configuration and click On.
- Set both Administrators and Users to Off, then click OK.
Why disable IE Enhanced Security?
Windows Server locks down Internet Explorer by default, blocking most downloads. Disabling this lets you download the JDK installer. This is safe for a temporary lab instance.
- Open Internet Explorer or Edge on the server.
- Navigate to https://adoptium.net/temurin/releases/.
- Select JDK 21 - LTS from the version dropdown, Windows as the OS, and x64 as the architecture.
- Download and run the .msi installer.
- On the Custom Setup screen, enable Set JAVA_HOME variable and Add to PATH.
- Complete the installer.
- Close your current Command Prompt and open a new one so the PATH changes take effect.
- Verify Java is installed by running this command:
java -version
You should see output starting with openjdk version "21.
- Confirm keytool is accessible by running:
keytool -version
'java' is not recognized?
Close Command Prompt completely and open a new one. Environment variable changes from the installer only apply to new sessions. If it still fails, verify JAVA_HOME is set by running echo %JAVA_HOME%.
Help me troubleshoot why java is not recognized after installing JDK 21 on Windows Server.
Locate and back up cacerts
The cacerts file is Java's default truststore. It contains the root certificates Java trusts when making SSL/TLS connections.
- Confirm the cacerts file exists by running:
dir "%JAVA_HOME%\lib\security\cacerts"
You should see a file listing showing cacerts with its size and date.
- Create a backup of cacerts before making any changes by running:
copy "%JAVA_HOME%\lib\security\cacerts" "%JAVA_HOME%\lib\security\cacerts.backup"
- Verify the backup exists by running:
dir "%JAVA_HOME%\lib\security\cacerts*"
You should see both cacerts and cacerts.backup listed with identical file sizes.
List the trusted certificates
- List all certificate entries in cacerts by running:
keytool -list -cacerts
- When prompted for the keystore password, type changeit and press Enter. This is the default password for the cacerts keystore.
What is cacerts?
The cacerts file is a PKCS12 keystore bundled with every JDK. It ships pre-loaded with root certificates from major Certificate Authorities like DigiCert and Let's Encrypt.
When a Java application makes an HTTPS connection, it checks the server's certificate against the entries in cacerts. If the chain does not trace back to an entry in this file, the connection is rejected.
You should see a summary showing the keystore type (PKCS12) and the total number of entries (typically 80+). This confirms keytool can read your truststore.
Java is installed and your truststore is backed up. Next up, you will prove that Java's HTTPS trust actually works before you break it.
Prove Java's HTTPS Trust Works
You installed Java and confirmed your truststore has 80+ root certificates loaded. Before you break anything, you need a baseline: proof that Java can successfully make an HTTPS connection right now.
In this step, you will write a tiny Java program that connects to an HTTPS endpoint, run it, and confirm it succeeds. This gives you a clear before-and-after comparison when you break the trust chain next.
In this step, get ready to:
- Write a Java program that makes an HTTPS call.
- Run it and confirm the connection succeeds.
- Inspect the remote server's certificate chain with keytool.
Create a Java HTTPS test program
You need a simple program that proves Java trusts a remote server's certificate. This program connects to Google's homepage over HTTPS and prints the response code.
- Move to your Desktop by running this command:
cd %USERPROFILE%\Desktop
- Create the Java file by running:
notepad HttpsTest.java
- Click Yes when Notepad asks to create the file.
- Paste the following code into Notepad:
import java.net.HttpURLConnection;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
// Connects to an HTTPS endpoint and prints the response code
public class HttpsTest {
public static void main(String[] args) throws Exception {
// Target URL - uses Google because it has a well-known certificate chain
URL url = new URL("https://www.google.com");
// Open the HTTPS connection
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setRequestMethod("GET");
// Get the HTTP response code (triggers the SSL handshake)
int responseCode = conn.getResponseCode();
// Print the result
System.out.println("Response code: " + responseCode);
System.out.println("SSL handshake succeeded - Java trusts this server.");
}
}
What does this code do?
- HttpsURLConnection opens an HTTPS connection to the target URL.
- When getResponseCode() runs, Java performs the SSL/TLS handshake behind the scenes. It walks the server's certificate chain and checks each certificate against your cacerts truststore.
- If the chain is trusted, you get a 200 response. If not, Java throws an SSLHandshakeException before the response ever arrives.
- Save the file with Ctrl+S and close Notepad.
Compile and run the program
- Compile the Java file by running:
javac HttpsTest.java
- Run the program by running:
java HttpsTest
You should see:
Response code: 200
SSL handshake succeeded - Java trusts this server.
This confirms Java's truststore recognises Google's certificate chain. The connection works.
Seeing a connection error?
- If you see a timeout error, check that your EC2 security group allows outbound HTTPS traffic on port 443. The default security group allows all outbound traffic.
- If you see a compile error, make sure you saved the file as HttpsTest.java (case-sensitive) and the class name matches.
Help me troubleshoot my Java HTTPS connection on EC2.
Inspect the remote server's certificate chain
Now see exactly which certificates Java checked during that handshake. This is the same technique you would use to diagnose a failing connection.
- Inspect Google's certificate chain by running:
keytool -printcert -sslserver www.google.com:443
What is a certificate chain?
The output shows multiple certificates stacked together. This is the trust chain. It starts with the server's own certificate and works up to a root CA that your Java truststore recognizes.
When Java connects to an HTTPS server, it walks this chain from bottom to top. If it finds a matching root certificate in cacerts, the connection is trusted. If not, Java throws an SSL exception.
You should see a chain of 2-3 certificates. Note the root certificate's Owner name at the top. You will need this information in the next step.
Your baseline is established: Java trusts Google's certificate chain and the HTTPS call succeeds. Next up, you will break that trust and watch the same program fail.
Break the Trust Chain
Your Java program connects to Google over HTTPS without a problem. Time to simulate the real-world incident: a missing root certificate that breaks the trust chain.
In this step, you will delete the root CA certificate that Google's chain depends on, then run your program again and watch it fail with an SSL exception. This is exactly what happens in production when a certificate expires or gets removed during a JDK upgrade.
In this step, get ready to:
- Identify which root CA certificate Google's chain depends on.
- Delete that certificate from your truststore.
- Run your HTTPS program and watch it fail.
Identify the root CA alias in cacerts
From the previous step, you saw the root certificate at the top of Google's chain. Now you need to find its matching alias in your cacerts truststore.
- Search your cacerts for entries containing "globalsign" (Google's typical root CA) by running:
keytool -list -cacerts | findstr /i "globalsign"
- When prompted for the password, enter changeit.
What does findstr do?
The findstr /i command filters the keytool output to show only lines containing your search term (case-insensitive). This saves you from scrolling through 80+ entries manually.
You should see one or more alias names containing "globalsign". Note the exact alias name that matches the root CA you saw in the certificate chain.
Your root CA might be different
Google rotates its certificate chain periodically. If your chain showed a different root CA (like GTS Root R1), search for that name instead. The important thing is matching the root certificate at the top of the chain you saw in the previous step.
Delete the root CA from cacerts
This is the moment you intentionally break Java's trust. Deleting this certificate means Java will no longer recognise Google's certificate chain.
- Open an Administrator Command Prompt. Press the Windows key, type cmd, right-click Command Prompt, and select Run as administrator.
- Click Yes on the User Account Control prompt.
- Navigate to your Desktop by running:
cd %USERPROFILE%\Desktop
- Delete the root CA certificate from cacerts by running:
keytool -delete -alias "globalsignrootcar2" -cacerts -storepass changeit
What does this command do?
- -delete removes the entry identified by the alias from the keystore.
- -cacerts targets the system truststore directly.
- Once deleted, any Java application on this machine that depends on this root CA will fail to establish HTTPS connections to servers signed by it.
💡 Use your actual alias
Replace globalsignrootcar2 with the exact alias you found in the previous substep. Alias names are case-insensitive but must match the spelling exactly.
Watch the HTTPS connection fail
Before you run the program, predict what will happen. The root CA is gone from the truststore. What do you think Java will do when it tries to verify Google's certificate chain?
- Run your HTTPS test program again:
java HttpsTest
You should see an error like:
Exception in thread "main" javax.net.ssl.SSLHandshakeException: PKIX path building failed
The same program that returned 200 moments ago now crashes. Java cannot build a trust path because the root CA is missing from cacerts. This is the exact error you would see in a production incident.
Program still succeeds?
- Make sure you deleted the correct alias. Run keytool -list -cacerts | findstr /i "globalsign" again to confirm the entry is gone.
- Google's chain might use a different root CA than expected. Run keytool -printcert -sslserver www.google.com:443 again and check which root is at the top of the chain. Delete that one instead.
Help me figure out which certificate to delete to break Google's trust chain.
You have a broken server. Java cannot make HTTPS connections to anything signed by that root CA. Next up, you will diagnose the problem and repair it.
Diagnose and Repair the Certificate Failure
Your Java application is throwing SSLHandshakeException. In a real incident, you would not know exactly what was deleted. You need to diagnose the root cause, find the missing certificate, and import it back into the truststore.
In this step, you will work through the diagnostic process a sysadmin would use: inspect the remote chain, compare it against your truststore, export the missing certificate, and import it to restore trust.
In this step, get ready to:
- Diagnose which certificate is missing from the truststore.
- Export and import the missing root CA certificate.
- Verify the HTTPS connection works again.
Diagnose the missing certificate
The error message says "PKIX path building failed." This means Java could not build a path from the server's certificate to a trusted root. Your job is to find out which root is missing.
- Inspect the server's certificate chain by running:
keytool -printcert -sslserver www.google.com:443
Look at the root certificate at the top of the chain. Note the Owner field. This is the certificate your truststore needs but does not have.
- Confirm it is missing from your cacerts by searching for it:
keytool -list -cacerts | findstr /i "globalsign"
- Enter changeit when prompted.
You should see no results (or fewer entries than before). This confirms the root CA is missing from your truststore.
How would you diagnose this in production?
In a real incident, you would: (1) check the application logs for the SSL exception, (2) use keytool -printcert -sslserver to see what the server presents, (3) compare the root of that chain against your cacerts entries. The gap between what the server needs and what your truststore has is always the answer.
Export the root certificate from the chain
You know which certificate is missing. Now you need to get a copy of it. You will export it directly from the server's chain into a PEM file.
- Export the certificate chain from the remote server by running:
keytool -printcert -sslserver www.google.com:443 -rfc > google_chain.pem
What does this command do?
- -rfc outputs the certificates in PEM (Base64) format instead of human-readable text.
- > google_chain.pem redirects the output to a file. This file contains all certificates in the chain.
- You need to extract just the root certificate from this file to import into cacerts.
- View the exported chain file by running:
type google_chain.pem
You should see multiple certificate blocks (each starting with -----BEGIN CERTIFICATE-----). The last block is the root CA certificate you need.
- Open the chain file in Notepad to extract the root certificate:
notepad google_chain.pem
- Select and copy the LAST certificate block (from -----BEGIN CERTIFICATE----- to -----END CERTIFICATE-----, inclusive).
- Open a new Notepad window by running:
notepad root_ca.pem
- Click Yes to create the file.
- Paste the root certificate block and save with Ctrl+S.
- Close both Notepad windows.
- Verify the extracted root certificate by running:
keytool -printcert -file root_ca.pem
You should see the certificate details showing the same Owner name you identified as the missing root CA.
Import the root certificate and verify the fix
Now import the missing root CA back into your truststore. Make sure you are in the Administrator Command Prompt for this step.
- Import the root certificate into cacerts by running:
keytool -importcert -alias "restored-root-ca" -file root_ca.pem -cacerts -storepass changeit
- When keytool asks Trust this certificate?, type yes and press Enter.
Why verify before trusting?
Notice that this time you did NOT use -noprompt. Keytool displays the certificate's fingerprint and asks you to confirm trust. In production, you would compare this fingerprint against the CA's official published fingerprint before saying yes.
The -noprompt flag skips this verification. Only use it in automated scripts where the certificate has already been verified through other means.
You should see Certificate was added to keystore. Now prove the fix works.
- Run your HTTPS test program again:
java HttpsTest
You should see:
Response code: 200
SSL handshake succeeded - Java trusts this server.
The connection is restored. You diagnosed the missing certificate, extracted it from the server's chain, imported it into the truststore, and proved the fix works.
Still seeing the SSL error?
- Verify the import succeeded by running keytool -list -cacerts -alias "restored-root-ca" (enter changeit when prompted).
- Make sure you extracted the LAST certificate block from the chain file. The first block is the server's leaf certificate, not the root.
- If you used a different alias during deletion, you may have deleted a different certificate than the one in the chain. Check the chain again with keytool -printcert -sslserver www.google.com:443.
Help me fix the SSL error after importing the root certificate.
Secret mission
Migrate Certificates Between Keystore Formats
In production environments, you often need to convert keystores between formats. Legacy Java applications use JKS, but modern systems expect PKCS12. Can you use -importkeystore to migrate certificates between these formats and back again?
Clean Up Your Resources
Clean Up Your Resources
Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project runs entirely locally, so there are no ongoing costs.
Resources you used:
- Keystore files in your working directory: teststore.jks, legacy.jks, modern.p12, converted.jks, testcacerts.jks.
- Certificate files in your working directory: testcert.pem, exported_cert.pem.
- Procedures document: keytool_procedures.txt.
- Backup file: cacerts.backup at %JAVA_HOME%\lib\security\cacerts.backup.
- JDK 21 installation (only if you installed it specifically for this project).
Keep everything running
No action needed. Choose this if you plan to continue working with Java certificates or want to reference the files later.
- Your keystore and certificate files remain in your working directory for future practice.
- Your keytool_procedures.txt file is a handy reference for day-to-day certificate management.
- The cacerts.backup file stays in your JDK security directory as a safety net.
- JDK 21 stays installed on your system. It takes no ongoing resources when idle.
Pause - I'll come back to this later
There are no running processes to stop. Your files sit on disk and consume minimal space.
- No action required. All project files are static keystores and certificates that use no memory or CPU.
- When you return, open Command Prompt as Administrator and navigate to your working directory to pick up where you left off.
Delete - I don't want to use this again
Remove all project files and optionally uninstall JDK 21.
- Delete the keystore and certificate files from your working directory by running this command in Command Prompt:
del teststore.jks testcert.pem exported_cert.pem testcacerts.jks legacy.jks modern.p12 converted.jks keytool_procedures.txt
- Delete the cacerts backup file by running:
del "%JAVA_HOME%\lib\security\cacerts.backup"
- Confirm the files are gone by running:
dir
You should no longer see any of the project files listed.
- To uninstall JDK 21 (only if you installed it for this project): press the Windows key, type Add or remove programs, and press Enter.
- Find the JDK 21 entry in the list, click it, then click Uninstall.
- Follow the on-screen prompts to complete the removal.
Nice Work!
Nice Work!
Congratulations! You now have hands-on experience managing Java's certificate infrastructure using keytool and the cacerts truststore on Windows.
You've learned how to:
- Located, backed up, and inspected the Java cacerts truststore using keytool -list with -cacerts, -v, and -alias options.
- Generated a self-signed certificate and imported it into the system truststore using keytool -importcert.
- Exported certificates in PEM format, deleted certificates by alias, and changed the keystore password with keytool -storepasswd.
- Migrated certificates between PKCS12 and JKS keystore formats using keytool -importkeystore.
Ready to quiz yourself?