Here's one solution using ASN1js and PKI.js. I've added a random raw hex certificate in DER format for demonstration purposes. In my testing the libraries add about 85 kB of unminified code to the build, which isn't too bad considering the complexity of this operation.
// Import only required components of 3rd-party libraries
import Certificate from 'pkijs/src/Certificate';
import {fromBER} from 'asn1js';
const X509_COMMON_NAME_KEY = '2.5.4.3';
const hexCertificateString = '308204273082030fa003020102020211e1300d06092a864886f70d01010b05003081bd310b3009060355040613025553310d300b06035504080c0455746168310e300c06035504070c0550726f766f3121301f060355040a0c184d6963726f666f63757320496e7465726e6174696f6e616c311a3018060355040b0c11416363657373204d616e6167656d656e74311f301d06035504030c164175746f6d6174696f6e20456e67696e656572696e67312f302d06092a864886f70d01090116206368726973746f706865722e6b656c6c79406d6963726f666f6375732e636f6d301e170d3139303330343137333430365a170d3231303330333137333430365a307b311d301b06035504030c147365727665722e6d79636f6d70616e792e636f6d310d300b06035504080c0455746168310b300906035504061302555331223020060355040a0c194d6963726f20466f63757320496e7465726e6174696f6e616c311a3018060355040b0c11416363657373204d616e6167656d656e7430820122300d06092a864886f70d01010105000382010f003082010a0282010100e3ed299a22551d3b4ae0e86a438f33ad3749a1152b3b6f50c39ae48f0a99550ac87287c7e5904ae466aacd72d044090a479554bce473c6b6342d0c2bf718d89656f33414daf599065d8610cb3ca74bed95149379608b3e0ec7db2916901e09099ad31d5f13f25f2db6fbc6fa479c6613ac35766cd6562555580f1ddcc57f4ab46a61bc682c40a06be060e620c92f167613584f34d3efb39cd29ebcb24c084554e5759ad814886f0b2c1b863565736113650a76b05f9d755f1fa3c9aa82e9cebf21155d2b481096036888641a5910d4feb3eb23a1d2900a84587047708033aed977200753fa15edac6960626dbc203baf084770e50e8a4c5dc3fb2cbb19c438c70203010001a3723070300c0603551d130101ff04023000301d0603551d0e04160414737228fc878e6e592d60b0c39cac757fcc4a9e1a301f0603551d230418301680144db5ee67429dcd2643d92d15a65efc681f399723300b0603551d0f0404030201a630130603551d25040c300a06082b06010505070301300d06092a864886f70d01010b05000382010100c9b8844b92e239c26f29d55fc2d969f1f977e8ad3967fd4274cf023668abed35b7c13d8cfc109711f48f13c0bbc2181abbad5ef1982ae17f6f7ef7de0b221d109327ed667d3a2e8ab0e1e39093798f236a70f16338bea07f6f74e1a07755768db6c3312083acf3e6ef6c4f1711ddea2049bbfb4dd262d692ad7146e29f83d19de3132b243de5e73bd537f2bd8198ee875fc2b64a52a9a600b870fd9a9a0d9569c44a6725244ce51d659100e26c22c42db72ad42ed9dc5ab40640d94e2f55ee082dd6f4221f2e23394e2c9c0c10590d67b0ec0e7af455724d1f5811c3728a9432ba161526bba500c9c37fc3d34afe9fbe108c9c6863a2b7b502b9fd5cf0c4ac50';
let commonName = ''; // Default in case no subject is found
try {
// Convert to ArrayBuffer
const typedArray = new Uint8Array(hexCertificateString.match(/[\da-f]{2}/gi)
.map(h => parseInt(h, 16)));
const certificateBuffer = typedArray.buffer;
// Parse certificate. See example at
// https://github.com/PeculiarVentures/PKI.js#parse-a-x509-certificate
const asn1 = fromBER(certificateBuffer);
const certificate = new Certificate({ schema: asn1.result });
// Search the subject's attributes for the common name of the certificate
const subjectAttributes = certificate.subject.typesAndValues;
for (let index = 0; index < subjectAttributes.length; index++) {
const attribute = subjectAttributes[index];
if (attribute.type === X509_COMMON_NAME_KEY) {
commonName = attribute.value.valueBlock.value;
break;
}
}
}
catch (error) {
console.error('Error parsing certificate:', error);
}
console.log('Certificate name:', commonName);