Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java get subject key identifier from certificate X509Certificate

I have p7b-file with some certificate inside, I open it in Java and get Subject with this code:

 try (InputStream inputStream = new FileInputStream("D:\\test.p7b")) {
       final CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
       certificateFactory.generateCertificates(inputStream).forEach(certificate -> {
           final X509Certificate x509Certificate = (X509Certificate) certificate;
           System.out.println("subjectDN: " + x509Certificate.getSubjectDN().getName());   
           
                System.out.println("__" + x509Certificate.getExtensionValue("2.5.29.14").hashCode() );
        
           System.out.println("*************************");
       });
   }

It's work fine, but I need to get Subject Key Identifier like this:

enter image description here

and it must be only on free Java without bouncycastle or any other framework. Please help, how to do it? Thanks!


1 Answers

UPD:

There is an option to use bouncycastle lib for this purpose where you generate

CMSSignedData signedData = new CMSSignedData(bytes);

and then you can get X509CertificateHolder and retrieve subject public key, serial number and other. You easily can convert X509CertificateHolder to X509Certificate and back

new JcaX509CertificateConverter().getCertificate(your X509CertificateHolder)
new JcaX509CertificateHolder(your x509Certificate)

____

You can get Subject Key Identifier this way:

byte[] ski = ((X509CertImpl) certificate).getSubjectKeyId().getIdentifier();

String subjectKeyId = bytesToHex(ski);

public String bytesToHex(byte[] bytes) {
        char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = HEX_ARRAY[v >>> 4];
            hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
        }
        return new String(hexChars);
    }

You can get all parameters using X509CertImpl e.g.

String serialNumber = bytesToHex(((X509CertImpl) certificate).getSerialNumberObject().getNumber().toByteArray())

There might be issue with import of X509Impl, so you have to add in your pom file following plugin:

             <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                    <release combine.self="override"></release>
                    <compilerArgs>
                        <arg>--add-exports</arg>
                        <arg>java.base/sun.security.x509=ALL-UNNAMED</arg>
                    </compilerArgs>
                </configuration>
            </plugin>
like image 97
Front-end Padavan Avatar answered Jan 22 '26 04:01

Front-end Padavan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!