diff --git a/core-java-modules/core-java-security-4/pom.xml b/core-java-modules/core-java-security-4/pom.xml
index cca86d804a..aae33f87d4 100644
--- a/core-java-modules/core-java-security-4/pom.xml
+++ b/core-java-modules/core-java-security-4/pom.xml
@@ -13,4 +13,22 @@
0.0.1-SNAPSHOT
+
+
+ org.bouncycastle
+ bcpkix-jdk15on
+ ${bouncycastle.version}
+
+
+ org.cryptacular
+ cryptacular
+ ${cryptacular.version}
+
+
+
+
+ 1.70
+ 1.2.6
+
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-security-4/src/main/resources/Baeldung.cer b/core-java-modules/core-java-security-4/src/main/resources/Baeldung.cer
new file mode 100644
index 0000000000..72d0918424
--- /dev/null
+++ b/core-java-modules/core-java-security-4/src/main/resources/Baeldung.cer
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDPjCCAiagAwIBAgIJAPvd1gx14C3CMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV
+BAYTAk1BMRAwDgYDVQQIEwdNb3JvY2NvMRMwEQYDVQQHEwpDYXNhYmxhbmNhMREw
+DwYDVQQDEwhCYWVsZHVuZzAeFw0xNzEwMTIxMDQzMTRaFw0yNzEwMTMxMDQzMTRa
+MEcxCzAJBgNVBAYTAk1BMRAwDgYDVQQIEwdNb3JvY2NvMRMwEQYDVQQHEwpDYXNh
+YmxhbmNhMREwDwYDVQQDEwhCYWVsZHVuZzCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAMyi5GmOeN4QaH/CP5gSOyHX8znb5TDHWV8wc+ZT7kNU8zt5tGMh
+jozK6hax155/6tOsBDR0rSYBhL+Dm/+uCVS7qOlRHhf6cNGtzGF1gnNJB2WjI8oM
+AYm24xpLj1WphKUwKrn3nTMPnQup5OoNAMYl99flANrRYVjjxrLQvDZDUio6Iujr
+CZ2TtXGM0g/gP++28KT7g1KlUui3xtB0u33wx7UN8Fix3JmjOaPHGwxGpwP3VGSj
+fs8cuhqVwRQaZpCOoHU/P8wpXKw80sSdhz+SRueMPtVYqK0CiLL5/O0h0Y3le4IV
+whgg3KG1iTGOWn60UMFn1EYmQ18k5Nsma6UCAwEAAaMtMCswCQYDVR0TBAIwADAR
+BglghkgBhvhCAQEEBAMCBPAwCwYDVR0PBAQDAgUgMA0GCSqGSIb3DQEBBQUAA4IB
+AQC8DDBmJ3p4xytxBiE0s4p1715WT6Dm/QJHp0XC0hkSoyZKDh+XVmrzm+J3SiW1
+vpswb5hLgPo040YX9jnDmgOD+TpleTuKHxZRYj92UYWmdjkWLVtFMcvOh+gxBiAP
+pHIqZsqo8lfcyAuh8Jx834IXbknfCUtERDLG/rU9P/3XJhrM2GC5qPQznrW4EYhU
+CGPyIJXmvATMVvXMWCtfogAL+n42vjYXQXZoAWomHhLHoNbSJUErnNdWDOh4WoJt
+XJCxA6U5LSBplqb3wB2hUTqw+0admKltvmy+KA1PD7OxoGiY7V544zeGqJam1qxU
+ia7y5BL6uOa/4ShSV8pcJDYz
+-----END CERTIFICATE-----
diff --git a/core-java-modules/core-java-security-4/src/test/java/com/baeldung/certificate/ExtractCommonNameUnitTest.java b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/certificate/ExtractCommonNameUnitTest.java
new file mode 100644
index 0000000000..91e40453ea
--- /dev/null
+++ b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/certificate/ExtractCommonNameUnitTest.java
@@ -0,0 +1,94 @@
+package com.baeldung.certificate;
+
+import org.bouncycastle.asn1.x500.RDN;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x500.style.BCStyle;
+import org.bouncycastle.asn1.x500.style.IETFUtils;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.cryptacular.util.CertUtil;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import javax.naming.ldap.LdapName;
+import javax.naming.ldap.Rdn;
+import javax.security.auth.x500.X500Principal;
+import java.io.FileInputStream;
+import java.security.Security;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class ExtractCommonNameUnitTest {
+
+ private static final String EXPECTED_CN = "Baeldung";
+
+ private String certificatePath = "src/main/resources/Baeldung.cer";
+
+ private X509Certificate certificate;
+
+ @BeforeEach
+ public void setUp() throws Exception {
+ Security.addProvider(new BouncyCastleProvider());
+ CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509", "BC");
+ certificate = (X509Certificate) certificateFactory.generateCertificate(new FileInputStream(certificatePath));
+ }
+
+ @Test
+ void whenUsingBouncyCastle_thenExtractCommonName() {
+ X500Principal principal = certificate.getSubjectX500Principal();
+ X500Name x500Name = new X500Name(principal.getName());
+ RDN[] rdns = x500Name.getRDNs(BCStyle.CN);
+ List names = new ArrayList<>();
+ for (RDN rdn : rdns) {
+ String name = IETFUtils.valueToString(rdn.getFirst().getValue());
+ names.add(name);
+ }
+
+ for (String commonName : names) {
+ assertEquals(EXPECTED_CN, commonName);
+ }
+ }
+
+ @Test
+ void whenUsingLDAPAPI_thenExtractCommonName() throws Exception {
+ X500Principal principal = certificate.getSubjectX500Principal();
+ LdapName ldapDN = new LdapName(principal.getName());
+ List names = new ArrayList<>();
+ for (Rdn rdn : ldapDN.getRdns()) {
+ if (rdn.getType().equalsIgnoreCase("cn")) {
+ String name = rdn.getValue().toString();
+ names.add(name);
+ }
+ }
+
+ for (String commonName : names) {
+ assertEquals(EXPECTED_CN, commonName);
+ }
+ }
+
+ @Test
+ void whenUsingCryptacular_thenExtractCommonName() {
+ String commonName = CertUtil.subjectCN(certificate);
+ assertEquals(EXPECTED_CN, commonName);
+ }
+
+ @Test
+ void whenUsingRegex_thenExtractCommonName() {
+ X500Principal principal = certificate.getSubjectX500Principal();
+ List names = new ArrayList<>();
+ Pattern pattern = Pattern.compile("CN=([^,]+)");
+ Matcher matcher = pattern.matcher(principal.getName());
+ while (matcher.find()) {
+ names.add(matcher.group(1));
+ }
+
+ for (String commonName : names) {
+ assertEquals(EXPECTED_CN, commonName);
+ }
+ }
+}