Javascript 从DER证书中提取公共名称

Javascript 从DER证书中提取公共名称,javascript,browser,cryptography,Javascript,Browser,Cryptography,如何从以DER格式表示证书的十六进制字符串中提取公共名称?我需要显示证书的名称,以便客户端可以选择他们希望在web应用程序中使用的证书 限制条件: 我需要在web浏览器的客户端执行此提取。OpenSSL将不可用 带有第三方库的解决方案的总大小应尽可能小 这里有一个使用ASN1js和PKI.js的解决方案。为了演示,我添加了一个DER格式的随机原始十六进制证书。在我的测试中,库向构建中添加了大约85KB的未统一代码,考虑到此操作的复杂性,这还不算太糟糕 // Import only requir

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

限制条件:

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

    • 这里有一个使用ASN1js和PKI.js的解决方案。为了演示,我添加了一个DER格式的随机原始十六进制证书。在我的测试中,库向构建中添加了大约85KB的未统一代码,考虑到此操作的复杂性,这还不算太糟糕

      // 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);
      
      //仅导入第三方库的必需组件
      从“pkijs/src/Certificate”导入证书;
      从'asn1js'导入{fromBER};
      const X509_COMMON_NAME_KEY='2.5.4.3';
      常数='308204273082030FA00302012021E13000D06092A864886F70D01010B05003081BD310B30090603550406130255310D300B060355040C00455746168310E300C06035504070C0550726F766F3121301F00655040A0C184D69637626F666F6375732046E7465726E617616C311A3018060355040C1141636363637373732040D616716D6167565656F7676161616E616476767676766E6175767676766F616464646464646E67312F302D06092A864886F70D010901162063687269737746F7066865722E96656C6C79406D69633726F666F6375732E636F6D301E170D31393033303313733340365A170D32313033303313331373333430365A307B311D301B06035504030C14736572776722E79636F6D70616E792E636F6D310D300B060355040804574616100C503555563636363636376767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767696F6E616C311A3018060355040B0C1141636573204D616E6167656D656E7430820300D06092A864886F70D01010105000382010F003082010A02820100E3ED299A22551D3B4AE0E86A438F33AD3749A1152B3B6F50C39AE48F0A99550AC87287C7E59044AE466AACD72D044090A479554BCE4773C66342D0C2BF718D8965F33414DAF5965867B37B1695FB01695F2017F495F2017F495F495F637F2017F497F2017F495F497F495F317F495F317F497F417F417B7B7B6F497F417B7B6F907F9C6613AC35766CD656255580F1DDCC57F4AB46A61BC682C40A06BE060E620C92F167613584F34D3EFB39CD29EBCB24C084554E5759AD814886F0B2C1B8635736113650A76B05F9D755F1FA3C9AA82E9CEBF21155D2B481096036888641A5910D4FEB32EB23A1D2900A8458707070803ED977200753FA15EDAC60626C6759AD81803BAF0080E50E505E57080C0037CF0101905CF080101905CF0170035CF01805CF0101905CF01905CF01905CF01737CF01905C51D0E04160414737228FC878E6E592D60B0C39CAC757FCC4A9E1A301F0603551D230418301680144DB5EE67429DCD2643D92D15A65EFC681F399723300B0603551D0404030201A6301030551D250C300A06082B00605070301300D06092A864886F70D01010B05000382010109B8844B92E239C26F29D55FC2D969F169F687E8F239CF4274CF02367CFC101987B221D109327ED667D3A2E8AB0E1E39093798F236A70F1638BEA07F6F74E1A07755768DB6C331208ACF3E6EF6C4F1711DEA2049BBFB4DD262D692AD7146E29F83D19DE3132B2435E73BD537F2BD8198EE875FC2B64A52A6600B870FD9AD9AD69C4725244CE51D659100E26C22C2C427DB72AD425DC5AB40640D945EED625B2435EE535F462EB537F2737BF457CF257B1957CF727CF727B1957CF727B1957CF727B1957CF727CF727CF727B727B727B1957CF727CF727B727CF727B727CF727CF727B1528CF727CF727CF727B134AFE9FBE108C9C6863A2B7B020B9FD5CF0C4AC50';
      让commonName=“”;//如果未找到主题,则为默认值
      试一试{
      //转换为ArrayBuffer
      const typedArray=new Uint8Array(hexCertificateString.match(/[\da-f]{2}/gi)
      .map(h=>parseInt(h,16));
      常数certificateBuffer=类型Darray.buffer;
      //解析证书。请参阅
      // https://github.com/PeculiarVentures/PKI.js#parse-a-x509-证书
      常数asn1=fromBER(证书缓冲);
      const certificate=新证书({schema:asn1.result});
      //在主题的属性中搜索证书的通用名称
      const subjectAttributes=certificate.subject.types和values;
      for(让index=0;index
      请参见