从DER证书中提取通用名称

时间:2019-03-05 23:34:13

标签: javascript browser cryptography

如何从表示DER格式的证书的十六进制字符串中提取通用名称?我需要显示证书的名称,以便客户端可以选择他们希望在Web应用程序中使用的证书。

约束:

  • 我需要在Web浏览器中执行此提取客户端。 OpenSSL将不可用。
  • 带有第三方库的解决方案的总大小应尽可能小。

1 个答案:

答案 0 :(得分:0)

这是使用ASN1js和PKI.js的一种解决方案。为了演示,我添加了DER格式的随机原始十六进制证书。在我的测试中,这些库向构建中添加了约85 kB的未压缩代码,考虑到此操作的复杂性,这还不错。

// 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);
相关问题