ssl Firefox忽略我的自签名CA证书

piztneat  于 2021-06-20  发布在  其他
关注(0)|答案(1)|浏览(266)

我通过以下代码创建了一个CA证书:

  1. // Create a new certificate authority (CA) key pair
  2. const caKeys = forge.pki.rsa.generateKeyPair(4096);
  3. // Create a new certificate authority (CA) certificate
  4. const cert = forge.pki.createCertificate();
  5. cert.publicKey = caKeys.publicKey;
  6. cert.signatureAlgorithm = forge.pki.oids.sha256WithRSAEncryption;
  7. cert.serialNumber = "01";
  8. // Set the subject of the CA certificate
  9. cert.setSubject([
  10. { name: "countryName", value: "SK" },
  11. { name: "commonName", value: "Primantro-Canny-Root-CA" },
  12. ]);
  13. // Set validity period of the CA certificate
  14. cert.validity.notBefore = new Date();
  15. cert.validity.notAfter = new Date();
  16. cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1); // 1 year validity
  17. var attrs = [
  18. { name: "commonName", value: "name" },
  19. { name: "countryName", value: "AT" },
  20. { name: "organizationName", value: "Org"},
  21. { shortName: "OU", value: "OU" },
  22. ];
  23. cert.setSubject(attrs);
  24. // alternatively set subject from a csr
  25. //cert.setSubject(csr.subject.attributes);
  26. cert.setIssuer(attrs);
  27. cert.setExtensions([
  28. { name: "basicConstraints", cA: true },
  29. {
  30. name: "keyUsage",
  31. keyCertSign: true,
  32. digitalSignature: true,
  33. nonRepudiation: true,
  34. keyEncipherment: true,
  35. dataEncipherment: true,
  36. },
  37. {
  38. name: "extKeyUsage",
  39. serverAuth: true,
  40. clientAuth: true,
  41. codeSigning: true,
  42. emailProtection: true,
  43. timeStamping: true,
  44. },
  45. {
  46. name: "nsCertType",
  47. client: true,
  48. server: true,
  49. email: true,
  50. objsign: true,
  51. sslCA: true,
  52. emailCA: true,
  53. objCA: true,
  54. },
  55. {
  56. name: "subjectKeyIdentifier",
  57. },
  58. ]);
  59. // Sign the CA certificate with its own private key
  60. cert.sign(caKeys.privateKey, forge.md.sha256.create());
  61. // Save the CA private key to a file
  62. const caPrivateKeyPem = forge.pki.privateKeyToPem(caKeys.privateKey);
  63. fs.writeFileSync(keyPath, caPrivateKeyPem);
  64. // Save the CA certificate to a file
  65. const caPublicPem = forge.pki.publicKeyToPem(cert.publicKey);
  66. fs.writeFileSync(pemPath, caPublicPem);
  67. // Convert the certificate to CRT format
  68. const crtCert = forge.pki.certificateToPem(cert);
  69. fs.writeFileSync(crtPath, crtCert);
  70. return { crt: crtCert, pem: caPublicPem, key: caPrivateKeyPem };

字符串
然后我使用返回的值为localhost创建一个ssl证书,代码如下:

  1. const ca = await localhostCA();
  2. const caPrivateKeyPem = ca.key;
  3. const caCertPem = ca.crt;
  4. const caPrivateKey = forge.pki.privateKeyFromPem(caPrivateKeyPem);
  5. const caCert = forge.pki.certificateFromPem(caCertPem);
  6. // Create a new key pair for the server
  7. const serverKeys = forge.pki.rsa.generateKeyPair(2048);
  8. const serverCert = forge.pki.createCertificate();
  9. serverCert.signatureAlgorithm = forge.pki.oids.sha256WithRSAEncryption;
  10. // Set the subject of the server certificate
  11. serverCert.publicKey = serverKeys.publicKey;
  12. serverCert.setSubject([
  13. { name: "countryName", value: "SK" },
  14. { name: "stateOrProvinceName", value: "YourState" },
  15. { name: "localityName", value: "YourCity" },
  16. { name: "organizationName", value: "Example-Certificates" },
  17. { name: "commonName", value: "localhost.local" },
  18. ]);
  19. // Set the issuer to the Root CA
  20. serverCert.setIssuer(caCert.subject.attributes);
  21. // Set the validity period of the server certificate
  22. serverCert.validity.notBefore = new Date();
  23. serverCert.validity.notAfter = new Date();
  24. serverCert.validity.notAfter.setFullYear(serverCert.validity.notBefore.getFullYear() + 1); // 1 year validity
  25. // Set the extensions for the server certificate
  26. serverCert.setExtensions([
  27. {
  28. name: "subjectAltName",
  29. altNames: [
  30. { type: 2, value: "localhost" },
  31. { type: 2, value: "fake1.local" },
  32. { type: 2, value: "fake2.local" },
  33. ],
  34. },
  35. {
  36. name: "keyUsage",
  37. keyEncipherment: true,
  38. digitalSignature: true,
  39. nonRepudiation: true,
  40. keyAgreement: true,
  41. },
  42. ]);
  43. // Sign the server certificate with the Root CA private key
  44. serverCert.sign(caPrivateKey, forge.md.sha256.create());
  45. // Save the server private key to a file
  46. const serverPrivateKeyPem = forge.pki.privateKeyToPem(serverKeys.privateKey);
  47. // fs.writeFileSync("localhost.key", serverPrivateKeyPem);
  48. // Save the server certificate request to a file (optional)
  49. // const serverCertReqPem = forge.pki.certificationRequestToPem(
  50. // forge.pki.createCertificationRequest({ publicKey: serverKeys.publicKey })
  51. // );
  52. // fs.writeFileSync("localhost.csr", serverCertReqPem);
  53. // Save the server certificate to a file
  54. const serverCertPem = forge.pki.certificateToPem(serverCert);
  55. // fs.writeFileSync("localhost.crt", serverCertPem);
  56. return {
  57. cert: serverCertPem,
  58. key: serverPrivateKeyPem,
  59. ca: ca.crt,
  60. };


然后我为节点的https服务器设置ssl证书,并在Firefox的证书管理器中的Authorities选项卡下导入CA证书。

  1. SEC_ERROR_UNKNOWN_ISSUER


我尝试用node-forge重新创建this tutorial,但显然没有成功。
当我将CA证书导入Windows存储时,Chrome可以正常工作并接受CA和SSL证书。但Firefox不接受。那么我如何使Firefox接受我自制的证书?

8iwquhpp

8iwquhpp1#

原来,证书是如此糟糕,他们基本上没有工作的任何地方。但我修复了它,这里的代码:

  1. function toPositiveHex(hexString) {
  2. var mostSiginficativeHexAsInt = parseInt(hexString[0], 16);
  3. if (mostSiginficativeHexAsInt < 8) {
  4. return hexString;
  5. }
  6. mostSiginficativeHexAsInt -= 8;
  7. return mostSiginficativeHexAsInt.toString() + hexString.substring(1);
  8. }
  9. const caAttrs = [
  10. {
  11. name: "commonName",
  12. value: "Company-CA",
  13. },
  14. {
  15. name: "countryName",
  16. value: "US",
  17. },
  18. {
  19. shortName: "OU",
  20. value: "Company-CA",
  21. },
  22. ];
  23. const siteAttrs = [
  24. {
  25. name: "commonName",
  26. value: "LocalWebsite",
  27. },
  28. {
  29. name: "countryName",
  30. value: "US",
  31. },
  32. {
  33. name: "organizationName",
  34. value: "LocalWebsite",
  35. },
  36. {
  37. shortName: "OU",
  38. value: "LocalWebsite",
  39. },
  40. ];
  41. async function generateCA(options = {}) {
  42. const keyPair = forge.pki.rsa.generateKeyPair(4096);
  43. const cert = forge.pki.createCertificate();
  44. cert.serialNumber = toPositiveHex(forge.util.bytesToHex(forge.random.getBytesSync(9))); // the serial number can be decimal or hex (if preceded by 0x)
  45. cert.validity.notBefore = new Date();
  46. cert.validity.notAfter = new Date();
  47. cert.validity.notAfter.setDate(cert.validity.notAfter.getDate() + (options.days || 1024));
  48. cert.setSubject(caAttrs);
  49. cert.publicKey = keyPair.publicKey;
  50. cert.setIssuer(caAttrs);
  51. cert.setExtensions([
  52. { name: "basicConstraints", cA: true },
  53. {
  54. name: "keyUsage",
  55. keyCertSign: true,
  56. digitalSignature: true,
  57. nonRepudiation: true,
  58. keyEncipherment: true,
  59. dataEncipherment: true,
  60. },
  61. {
  62. name: "subjectKeyIdentifier",
  63. keyIdentifier: cert.generateSubjectKeyIdentifier().getBytes(),
  64. },
  65. ]);
  66. cert.sign(keyPair.privateKey, forge.md.sha256.create());
  67. var pem = {
  68. private: forge.pki.privateKeyToPem(keyPair.privateKey),
  69. public: forge.pki.publicKeyToPem(keyPair.publicKey),
  70. cert: forge.pki.certificateToPem(cert),
  71. };
  72. return {
  73. crt: pem.cert,
  74. pem: pem.public,
  75. key: pem.private,
  76. };
  77. }
  78. async function generateForLocalhost(options = {}) {
  79. // Load the Root CA private key and certificate
  80. const ca = await generateCA();
  81. const caPrivateKey = forge.pki.privateKeyFromPem(ca.key);
  82. const caCert = forge.pki.certificateFromPem(ca.crt);
  83. var clientkeys = forge.pki.rsa.generateKeyPair(options.clientCertificateKeySize || 4096);
  84. var cert = forge.pki.createCertificate();
  85. cert.serialNumber = toPositiveHex(forge.util.bytesToHex(forge.random.getBytesSync(9)));
  86. cert.validity.notBefore = new Date();
  87. cert.validity.notAfter = new Date(new Date().setDate(new Date().getDate() + 7));
  88. cert.setIssuer(caAttrs);
  89. cert.setSubject(siteAttrs);
  90. cert.setExtensions([
  91. {
  92. name: "subjectAltName",
  93. altNames: [
  94. { type: 2, value: "localhost" },
  95. { type: 7, ip: "127.0.0.1" },
  96. { type: 7, ip: "192.168.0.193" },
  97. ],
  98. },
  99. {
  100. name: "keyUsage",
  101. keyEncipherment: true,
  102. digitalSignature: true,
  103. nonRepudiation: true,
  104. keyAgreement: true,
  105. },
  106. {
  107. name: "extKeyUsage",
  108. serverAuth: true,
  109. clientAuth: true,
  110. codeSigning: true,
  111. emailProtection: true,
  112. timeStamping: true,
  113. },
  114. {
  115. name: "authorityKeyIdentifier",
  116. keyIdentifier: caCert.generateSubjectKeyIdentifier().getBytes(),
  117. },
  118. ]);
  119. cert.publicKey = clientkeys.publicKey;
  120. // Sign client cert with root cert
  121. cert.sign(caPrivateKey, forge.md.sha256.create());
  122. const pem = {};
  123. pem.clientprivate = forge.pki.privateKeyToPem(clientkeys.privateKey);
  124. pem.clientpublic = forge.pki.publicKeyToPem(clientkeys.publicKey);
  125. pem.clientcert = forge.pki.certificateToPem(cert);
  126. return {
  127. cert: pem.clientcert,
  128. key: pem.clientprivate,
  129. ca: ca.crt,
  130. };
  131. }

字符串
有点不干净,所以按照你的喜好整理一下。

展开查看全部

相关问题