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

piztneat  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(96)

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

// Create a new certificate authority (CA) key pair
        const caKeys = forge.pki.rsa.generateKeyPair(4096);

        // Create a new certificate authority (CA) certificate
        const cert = forge.pki.createCertificate();
        cert.publicKey = caKeys.publicKey;
        cert.signatureAlgorithm = forge.pki.oids.sha256WithRSAEncryption;
        cert.serialNumber = "01";

        // Set the subject of the CA certificate
        cert.setSubject([
                { name: "countryName", value: "SK" },
                { name: "commonName", value: "Primantro-Canny-Root-CA" },
        ]);

        // Set validity period of the CA certificate
        cert.validity.notBefore = new Date();
        cert.validity.notAfter = new Date();
        cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1); // 1 year validity

        var attrs = [
                { name: "commonName", value: "name" },
                { name: "countryName", value: "AT" },
                { name: "organizationName", value: "Org"},
                { shortName: "OU", value: "OU" },
        ];
        cert.setSubject(attrs);
        // alternatively set subject from a csr
        //cert.setSubject(csr.subject.attributes);
        cert.setIssuer(attrs);
        cert.setExtensions([
                { name: "basicConstraints", cA: true },
                {
                        name: "keyUsage",
                        keyCertSign: true,
                        digitalSignature: true,
                        nonRepudiation: true,
                        keyEncipherment: true,
                        dataEncipherment: true,
                },
                {
                        name: "extKeyUsage",
                        serverAuth: true,
                        clientAuth: true,
                        codeSigning: true,
                        emailProtection: true,
                        timeStamping: true,
                },
                {
                        name: "nsCertType",
                        client: true,
                        server: true,
                        email: true,
                        objsign: true,
                        sslCA: true,
                        emailCA: true,
                        objCA: true,
                },
                {
                        name: "subjectKeyIdentifier",
                },
        ]);

        // Sign the CA certificate with its own private key
        cert.sign(caKeys.privateKey, forge.md.sha256.create());

        // Save the CA private key to a file
        const caPrivateKeyPem = forge.pki.privateKeyToPem(caKeys.privateKey);
        fs.writeFileSync(keyPath, caPrivateKeyPem);

        // Save the CA certificate to a file
        const caPublicPem = forge.pki.publicKeyToPem(cert.publicKey);
        fs.writeFileSync(pemPath, caPublicPem);

        // Convert the certificate to CRT format
        const crtCert = forge.pki.certificateToPem(cert);
        fs.writeFileSync(crtPath, crtCert);

        return { crt: crtCert, pem: caPublicPem, key: caPrivateKeyPem };

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

const ca = await localhostCA();

        const caPrivateKeyPem = ca.key;
        const caCertPem = ca.crt;

        const caPrivateKey = forge.pki.privateKeyFromPem(caPrivateKeyPem);
        const caCert = forge.pki.certificateFromPem(caCertPem);

        // Create a new key pair for the server
        const serverKeys = forge.pki.rsa.generateKeyPair(2048);
        const serverCert = forge.pki.createCertificate();
        serverCert.signatureAlgorithm = forge.pki.oids.sha256WithRSAEncryption;

        // Set the subject of the server certificate
        serverCert.publicKey = serverKeys.publicKey;
        serverCert.setSubject([
                { name: "countryName", value: "SK" },
                { name: "stateOrProvinceName", value: "YourState" },
                { name: "localityName", value: "YourCity" },
                { name: "organizationName", value: "Example-Certificates" },
                { name: "commonName", value: "localhost.local" },
        ]);

        // Set the issuer to the Root CA
        serverCert.setIssuer(caCert.subject.attributes);

        // Set the validity period of the server certificate
        serverCert.validity.notBefore = new Date();
        serverCert.validity.notAfter = new Date();
        serverCert.validity.notAfter.setFullYear(serverCert.validity.notBefore.getFullYear() + 1); // 1 year validity

        // Set the extensions for the server certificate
        serverCert.setExtensions([
                {
                        name: "subjectAltName",
                        altNames: [
                                { type: 2, value: "localhost" },
                                { type: 2, value: "fake1.local" },
                                { type: 2, value: "fake2.local" },
                        ],
                },
                {
                        name: "keyUsage",
                        keyEncipherment: true,
                        digitalSignature: true,
                        nonRepudiation: true,
                        keyAgreement: true,
                },
        ]);

        // Sign the server certificate with the Root CA private key
        serverCert.sign(caPrivateKey, forge.md.sha256.create());

        // Save the server private key to a file
        const serverPrivateKeyPem = forge.pki.privateKeyToPem(serverKeys.privateKey);
        // fs.writeFileSync("localhost.key", serverPrivateKeyPem);

        // Save the server certificate request to a file (optional)
        // const serverCertReqPem = forge.pki.certificationRequestToPem(
        //         forge.pki.createCertificationRequest({ publicKey: serverKeys.publicKey })
        // );
        // fs.writeFileSync("localhost.csr", serverCertReqPem);

        // Save the server certificate to a file
        const serverCertPem = forge.pki.certificateToPem(serverCert);
        // fs.writeFileSync("localhost.crt", serverCertPem);

        return {
                cert: serverCertPem,
                key: serverPrivateKeyPem,
                ca: ca.crt,
        };


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

SEC_ERROR_UNKNOWN_ISSUER


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

8iwquhpp

8iwquhpp1#

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

function toPositiveHex(hexString) {
        var mostSiginficativeHexAsInt = parseInt(hexString[0], 16);
        if (mostSiginficativeHexAsInt < 8) {
                return hexString;
        }

        mostSiginficativeHexAsInt -= 8;
        return mostSiginficativeHexAsInt.toString() + hexString.substring(1);
}

const caAttrs = [
        {
                name: "commonName",
                value: "Company-CA",
        },
        {
                name: "countryName",
                value: "US",
        },
        {
                shortName: "OU",
                value: "Company-CA",
        },
];
const siteAttrs = [
        {
                name: "commonName",
                value: "LocalWebsite",
        },
        {
                name: "countryName",
                value: "US",
        },
        {
                name: "organizationName",
                value: "LocalWebsite",
        },
        {
                shortName: "OU",
                value: "LocalWebsite",
        },
];

async function generateCA(options = {}) {
        const keyPair = forge.pki.rsa.generateKeyPair(4096);

        const cert = forge.pki.createCertificate();

        cert.serialNumber = toPositiveHex(forge.util.bytesToHex(forge.random.getBytesSync(9))); // the serial number can be decimal or hex (if preceded by 0x)

        cert.validity.notBefore = new Date();
        cert.validity.notAfter = new Date();
        cert.validity.notAfter.setDate(cert.validity.notAfter.getDate() + (options.days || 1024));

        cert.setSubject(caAttrs);

        cert.publicKey = keyPair.publicKey;

        cert.setIssuer(caAttrs);
        cert.setExtensions([
                { name: "basicConstraints", cA: true },
                {
                        name: "keyUsage",
                        keyCertSign: true,
                        digitalSignature: true,
                        nonRepudiation: true,
                        keyEncipherment: true,
                        dataEncipherment: true,
                },
                {
                        name: "subjectKeyIdentifier",
                        keyIdentifier: cert.generateSubjectKeyIdentifier().getBytes(),
                },
        ]);

        cert.sign(keyPair.privateKey, forge.md.sha256.create());

        var pem = {
                private: forge.pki.privateKeyToPem(keyPair.privateKey),
                public: forge.pki.publicKeyToPem(keyPair.publicKey),
                cert: forge.pki.certificateToPem(cert),
        };
        return {
                crt: pem.cert,
                pem: pem.public,
                key: pem.private,
        };
}
async function generateForLocalhost(options = {}) {
        // Load the Root CA private key and certificate
        const ca = await generateCA();

        const caPrivateKey = forge.pki.privateKeyFromPem(ca.key);
        const caCert = forge.pki.certificateFromPem(ca.crt);

        var clientkeys = forge.pki.rsa.generateKeyPair(options.clientCertificateKeySize || 4096);
        var cert = forge.pki.createCertificate();
        cert.serialNumber = toPositiveHex(forge.util.bytesToHex(forge.random.getBytesSync(9)));
        cert.validity.notBefore = new Date();
        cert.validity.notAfter = new Date(new Date().setDate(new Date().getDate() + 7));

        cert.setIssuer(caAttrs);
        cert.setSubject(siteAttrs);
        cert.setExtensions([
                {
                        name: "subjectAltName",
                        altNames: [
                                { type: 2, value: "localhost" },
                                { type: 7, ip: "127.0.0.1" },
                                { type: 7, ip: "192.168.0.193" },
                        ],
                },
                {
                        name: "keyUsage",
                        keyEncipherment: true,
                        digitalSignature: true,
                        nonRepudiation: true,
                        keyAgreement: true,
                },
                {
                        name: "extKeyUsage",
                        serverAuth: true,
                        clientAuth: true,
                        codeSigning: true,
                        emailProtection: true,
                        timeStamping: true,
                },
                {
                        name: "authorityKeyIdentifier",
                        keyIdentifier: caCert.generateSubjectKeyIdentifier().getBytes(),
                },
        ]);

        cert.publicKey = clientkeys.publicKey;

        // Sign client cert with root cert
        cert.sign(caPrivateKey, forge.md.sha256.create());

        const pem = {};
        pem.clientprivate = forge.pki.privateKeyToPem(clientkeys.privateKey);
        pem.clientpublic = forge.pki.publicKeyToPem(clientkeys.publicKey);
        pem.clientcert = forge.pki.certificateToPem(cert);

        return {
                cert: pem.clientcert,
                key: pem.clientprivate,
                ca: ca.crt,
        };
}

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

相关问题