pkcs7.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. const pkijs = require("pkijs");
  2. const nodeCrypto = require("crypto");
  3. // Use Node.js native webcrypto
  4. const crypto = nodeCrypto.webcrypto;
  5. // Set up pkijs to use native crypto
  6. // Note: This modifies global pkijs state. If the consumer also uses pkijs,
  7. // they should set their own engine or use a version that supports per-instance engines.
  8. let pkijsInitialized = false;
  9. function ensurePkijsInitialized() {
  10. if (!pkijsInitialized) {
  11. pkijs.setEngine("nodeEngine", crypto, new pkijs.CryptoEngine({
  12. name: "",
  13. crypto: crypto,
  14. subtle: crypto.subtle
  15. }));
  16. pkijsInitialized = true;
  17. }
  18. }
  19. /**
  20. * Create PKCS#7 formatted certificate from PEM certificate
  21. *
  22. * @param {string} certPem - PEM formatted certificate
  23. * @returns {string} PKCS#7 PEM formatted certificate
  24. */
  25. function createPkcs7(certPem) {
  26. ensurePkijsInitialized();
  27. // Parse the PEM certificate to get raw data
  28. const certLines = certPem.split('\n').filter(line =>
  29. !line.includes('BEGIN CERTIFICATE') &&
  30. !line.includes('END CERTIFICATE') &&
  31. line.trim()
  32. );
  33. const certBase64 = certLines.join('');
  34. const certBuffer = Buffer.from(certBase64, 'base64');
  35. // Parse certificate using pkijs
  36. const asn1Cert = pkijs.Certificate.fromBER(certBuffer);
  37. // Create PKCS#7 SignedData structure
  38. const cmsSigned = new pkijs.SignedData({
  39. version: 1,
  40. encapContentInfo: new pkijs.EncapsulatedContentInfo({
  41. eContentType: "1.2.840.113549.1.7.1" // data
  42. }),
  43. certificates: [asn1Cert]
  44. });
  45. // Wrap in ContentInfo
  46. const cmsSignedSchema = cmsSigned.toSchema();
  47. const cmsContentInfo = new pkijs.ContentInfo({
  48. contentType: "1.2.840.113549.1.7.2", // signedData
  49. content: cmsSignedSchema
  50. });
  51. // Convert to DER and then PEM
  52. const cmsSignedDer = cmsContentInfo.toSchema().toBER(false);
  53. const pkcs7Pem =
  54. '-----BEGIN PKCS7-----\n' +
  55. Buffer.from(cmsSignedDer).toString('base64').match(/.{1,64}/g).join('\n') +
  56. '\n-----END PKCS7-----\n';
  57. return pkcs7Pem;
  58. }
  59. module.exports = { createPkcs7 };