Partner – Microsoft – NPI EA (cat = Baeldung)
announcement - icon

Azure Container Apps is a fully managed serverless container service that enables you to build and deploy modern, cloud-native Java applications and microservices at scale. It offers a simplified developer experience while providing the flexibility and portability of containers.

Of course, Azure Container Apps has really solid support for our ecosystem, from a number of build options, managed Java components, native metrics, dynamic logger, and quite a bit more.

To learn more about Java features on Azure Container Apps, visit the documentation page.

You can also ask questions and leave feedback on the Azure Container Apps GitHub page.

Partner – Microsoft – NPI EA (cat= Spring Boot)
announcement - icon

Azure Container Apps is a fully managed serverless container service that enables you to build and deploy modern, cloud-native Java applications and microservices at scale. It offers a simplified developer experience while providing the flexibility and portability of containers.

Of course, Azure Container Apps has really solid support for our ecosystem, from a number of build options, managed Java components, native metrics, dynamic logger, and quite a bit more.

To learn more about Java features on Azure Container Apps, you can get started over on the documentation page.

And, you can also ask questions and leave feedback on the Azure Container Apps GitHub page.

Partner – Orkes – NPI EA (cat=Spring)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Partner – Orkes – NPI EA (tag=Microservices)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – MongoDB – NPI EA (tag=MongoDB)
announcement - icon

Traditional keyword-based search methods rely on exact word matches, often leading to irrelevant results depending on the user's phrasing.

By comparison, using a vector store allows us to represent the data as vector embeddings, based on meaningful relationships. We can then compare the meaning of the user’s query to the stored content, and retrieve more relevant, context-aware results.

Explore how to build an intelligent chatbot using MongoDB Atlas, Langchain4j and Spring Boot:

>> Building an AI Chatbot in Java With Langchain4j and MongoDB Atlas

Partner – LambdaTest – NPI EA (cat=Testing)
announcement - icon

Accessibility testing is a crucial aspect to ensure that your application is usable for everyone and meets accessibility standards that are required in many countries.

By automating these tests, teams can quickly detect issues related to screen reader compatibility, keyboard navigation, color contrast, and other aspects that could pose a barrier to using the software effectively for people with disabilities.

Learn how to automate accessibility testing with Selenium and the LambdaTest cloud-based testing platform that lets developers and testers perform accessibility automation on over 3000+ real environments:

Automated Accessibility Testing With Selenium

1. Overview

Digital certificates are important in establishing trusted and secure online communication. We often use them to ensure the data exchanged between the client and the web server remains secure.

In this tutorial, we’ll explore how to determine in Java whether a given certificate is self-signed or signed by a trusted Certificate Authority (CA).

However, due to the diversity of certificates and security concepts, there is no one-size-fits-all solution. We often need to choose the best approach for our specific context and requirements.

2. Self-Signed vs. CA-Signed Certificate

First, let’s examine the differences between self-signed and CA-signed certificates.

Simply put, a self-signed certificate is generated and signed by the same entity. Even though it provides encryption, it doesn’t verify trust by an independent authority. In other words, it doesn’t involve any third-party Certificate Authority (CA).

Consequently, when a user’s web browser encounters a self-signed certificate, it may issue a security warning since the certificate’s authenticity can’t be independently verified.

We often use them in private networks and for testing purposes.

On the other hand, CA-signed certificates are signed by trusted Certificate Authorities. The majority of web browsers and operating systems recognize and accept these CAs.

Additionally, the CA-signed certificate proves the entity holding the certificate is the legitimate owner of the domain, helping users trust they’re communicating with the genuine server and not an intermediary.

Now, let’s see how to check whether we’re dealing with a self-signed or CA-signed certificate using Java.

3. Checking if the Certificate Is Self-Signed

Before we start, let’s generate the certificate we’ll use throughout our examples. The easiest way to generate a self-signed certificate is with the keytool tool:

keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -validity 365 -keysize 2048

Here, we created a self-signed certificate with the selfsigned alias. Furthermore, we stored it inside the keysore.jks keystore.

3.1. Comparing Issuer and Subject Values

As previously mentioned, the same entity generates and signs a self-signed certificate.

The issuer part of the certificate represents the certificate’s signer. The self-signed certificate has the same value for the subject (Issued To) and the issuer (Issued By). To put it differently, to determine whether we’re dealing with a self-signed certificate, we’ll compare its subject and issuer information.

Furthermore, Java API provides the java.security.cert.X509Certificate class for dealing with certificates. With this class, we can interact with X.509 certificates and perform various checks and validations.

Let’s check whether the subject and issuer match. We can achieve this by extracting the relevant fields from the X509Certificate object and checking if they match:

@Test
void whenCertificateIsSelfSigned_thenSubjectIsEqualToIssuer() throws Exception {
    X509Certificate certificate = (X509Certificate) keyStore.getCertificate("selfsigned");
    assertEquals(certificate.getSubjectDN(), certificate.getIssuerDN());
}

3.2. Verifying the Signature

Another way we can check if we’re dealing with a self-signed certificate is to verify it using its own public key.

Let’s check the self-signed certificate using the verify() method:

@Test
void whenCertificateIsSelfSigned_thenItCanBeVerifiedWithItsOwnPublicKey() throws Exception {
    X509Certificate certificate = (X509Certificate) keyStore.getCertificate("selfsigned");
    assertDoesNotThrow(() -> certificate.verify(certificate.getPublicKey()));
}

However, if we pass the CA-signed certificate, the method would throw an exception.

4. Checking if the Certificate Is CA-Signed

To qualify as a CA-signed, a certificate must be part of a chain of trust leading back to a trusted root CA. Simply put, a certificate chain contains a list of certificates starting from the root certificate and ending with the user’s certificate. Each certificate in the chain signs the next certificate.

When we talk about the chain of trust, there are different certificate types:

  • Root Certificate
  • Intermediate Certificate
  • End Entity Certificate

Furthermore, we use the root and intermediate certificates of the hierarchy to issue and verify end entity certificates.

For the purposes of this tutorial, we’ll use the certificate obtained from the Baeldung site:

Baeldung certificate

The complexity of checking CA-signed certificates increases if the end entity certificate is part of a certificate chain. In such a scenario, we might need to examine the entire chain to determine if we have a CA-signed certificate. The issuer of the certificate might not be the root CA directly but rather an intermediate CA that signed with the root CA.

Now, if we examine the certificate hierarchy, we can see the certificate is part of a certificate chain:

Baeldung Certificate Hierarchy
  • Baltimore CyberTrust Root – Root CA
  • Cloudflare Inc ECC CA-3 – Intermediate CA
  • sni.cloudflaressl.com – End Entity (used on the Baeldung site)

4.1. Using Truststore

We can create our own truststore to check if one of the certificates we trust signed the end entity certificate.

When setting up a truststore, we typically include the root CA certificates as well as any intermediate CA certificates required to build the chain of trust. This way, our application can effectively validate certificates presented by other parties.

An advantage of using a truststore is the ability to decide which CA certificates we trust and which we don’t.

From our example, the Baltimore CyberTrust Root certificate signed the intermediate Cloudflare certificate, which signed our end entity certificate.

Now, let’s add both to our truststore:

keytool -importcert -file cloudflare.cer -keystore truststore.jks -alias cloudflare
keytool -importcert -file root.cer -keystore truststore.jks -alias root

Next, to check if we trust the given end entity certificate, we need to find a way to get the root certificate. Let’s create the getRootCertificate() method that searches for a root certificate:

public static X509Certificate getRootCertificate(X509Certificate endEntityCertificate, KeyStore trustStore)
        throws Exception {
    X509Certificate issuerCertificate = findIssuerCertificate(endEntityCertificate, trustStore);
    if (issuerCertificate != null) {
        if (isRoot(issuerCertificate)) {
            return issuerCertificate;
        } else {
            return getRootCertificate(issuerCertificate, trustStore);
        }
    }
    return null;
}

private static boolean isRoot(X509Certificate certificate) {
    try {
        certificate.verify(certificate.getPublicKey());
        return certificate.getKeyUsage() != null && certificate.getKeyUsage()[5];
    } catch (Exception e) {
        return false;
    }
}

First, we attempt to locate the issuer of a provided certificate within the trust store:

static X509Certificate findIssuerCertificate(X509Certificate certificate, KeyStore trustStore)
        throws KeyStoreException {
    Enumeration<String> aliases = trustStore.aliases();
    while (aliases.hasMoreElements()) {
        String alias = aliases.nextElement();
        Certificate cert = trustStore.getCertificate(alias);
        if (cert instanceof X509Certificate) {
            X509Certificate x509Cert = (X509Certificate) cert;
            if (x509Cert.getSubjectX500Principal().equals(certificate.getIssuerX500Principal())) {
                return x509Cert;
            }
        }
    }
    return null;
}

Then, if a match is discovered, we proceed to verify whether the certificate is a self-signed CA certificate. In the event of successful verification, we reach the root certificate. If not, we continue our search.

Finally, let’s test our method to check whether it works properly:

@Test
void whenCertificateIsCASigned_thenRootCanBeFoundInTruststore() throws Exception {
    X509Certificate endEntityCertificate = (X509Certificate) keyStore.getCertificate("baeldung");
    X509Certificate rootCertificate = getRootCertificate(endEntityCertificate, trustStore);
    assertNotNull(rootCertificate);
}

If we perform the same test using the self-signed certificate, we won’t get the root since our trust store doesn’t contain it.

5. Checking if the Certificate Is a CA Certificate

In cases when we’re dealing only with root or intermediate certificates, we may need to perform additional checks.

It’s important to note a root certificate is also a self-signed certificate. However, the difference between the root and the user’s self-signed certificate is the former will have the keyCertSign flag enabled (since we can use it to sign other certificates).

We can identify root or intermediate certificates by checking the key usage:

@Test
void whenCertificateIsCA_thenItCanBeUsedToSignOtherCertificates() throws Exception {
    X509Certificate certificate = (X509Certificate) keyStore.getCertificate("cloudflare");
    assertTrue(certificate.getKeyUsage()[5]);
}

Moreover, one of the checks we can perform is checking basic constraints extension.

The Basic Constraints extension is a field in X.509 certificates that provides information about the certificate’s intended usage and whether it represents a Certificate Authority (CA) or an end entity.

If the basic constraints extension doesn’t exist, the getBasicConstraints() method returns -1:

@Test
void whenCertificateIsCA_thenBasicConstrainsReturnsZeroOrGreaterThanZero() throws Exception {
    X509Certificate certificate = (X509Certificate) keyStore.getCertificate("cloudflare");
    assertNotEquals(-1, certificate.getBasicConstraints());
}

6. Conclusion

In this article, we learned how to check whether a certificate is self-signed or CA-signed.

To sum up, self-signed certificates have the same subject and issuer components, and additionally, they can be verified using their own public key.

On the other hand, CA-signed certificates are usually part of the certificate chain. To validate them, we need to create a trust store that contains the trusted root and intermediate certificates and check if the root of the end entity certificate matches one of the trusted certificates.

Finally, if we’re working with root or intermediate certificates, we can identify them by checking whether they’re used for signing other certificates or not.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

Partner – Microsoft – NPI EA (cat = Baeldung)
announcement - icon

Azure Container Apps is a fully managed serverless container service that enables you to build and deploy modern, cloud-native Java applications and microservices at scale. It offers a simplified developer experience while providing the flexibility and portability of containers.

Of course, Azure Container Apps has really solid support for our ecosystem, from a number of build options, managed Java components, native metrics, dynamic logger, and quite a bit more.

To learn more about Java features on Azure Container Apps, visit the documentation page.

You can also ask questions and leave feedback on the Azure Container Apps GitHub page.

Partner – Microsoft – NPI EA (cat = Spring Boot)
announcement - icon

Azure Container Apps is a fully managed serverless container service that enables you to build and deploy modern, cloud-native Java applications and microservices at scale. It offers a simplified developer experience while providing the flexibility and portability of containers.

Of course, Azure Container Apps has really solid support for our ecosystem, from a number of build options, managed Java components, native metrics, dynamic logger, and quite a bit more.

To learn more about Java features on Azure Container Apps, visit the documentation page.

You can also ask questions and leave feedback on the Azure Container Apps GitHub page.

Partner – Orkes – NPI EA (cat = Spring)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Partner – Orkes – NPI EA (tag = Microservices)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Partner – MongoDB – NPI EA (tag=MongoDB)
announcement - icon

Traditional keyword-based search methods rely on exact word matches, often leading to irrelevant results depending on the user's phrasing.

By comparison, using a vector store allows us to represent the data as vector embeddings, based on meaningful relationships. We can then compare the meaning of the user’s query to the stored content, and retrieve more relevant, context-aware results.

Explore how to build an intelligent chatbot using MongoDB Atlas, Langchain4j and Spring Boot:

>> Building an AI Chatbot in Java With Langchain4j and MongoDB Atlas

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Course – LSS – NPI (cat=Security/Spring Security)
announcement - icon

I just announced the new Learn Spring Security course, including the full material focused on the new OAuth2 stack in Spring Security:

>> CHECK OUT THE COURSE

eBook Jackson – NPI EA – 3 (cat = Jackson)
2 Comments
Oldest
Newest
Inline Feedbacks
View all comments