Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generating a cert using a CSR does not appear possible #80

Open
BrianOpteran opened this issue Jul 29, 2024 · 2 comments
Open

Generating a cert using a CSR does not appear possible #80

BrianOpteran opened this issue Jul 29, 2024 · 2 comments
Labels
help wanted Extra attention is needed

Comments

@BrianOpteran
Copy link

There doesn't seem to be the ability to generate an x509 certificate from a CSR and CA certificate. The flow I require is to create a new CA, then a CSR and then a service certificate from them both.

It looks like that's currently unsupported in this lib? Other than that, I was getting on very well with it.

@microshine microshine added the help wanted Extra attention is needed label Jul 29, 2024
@microshine
Copy link
Contributor

Actually, the @peculiar/x509 library does support generating x509 certificates from a Certificate Signing Request (CSR) and a Certificate Authority (CA) certificate. Here’s an example to illustrate how you can achieve this:

  1. Generate a Self-Signed CA Certificate:

    const caAlg = {
        name: "ECDSA",
        hash: "SHA-256",
        namedCurve: "P-256"
    };
    const caKeys = await crypto.subtle.generateKey(caAlg, true, ["sign", "verify"]);
    
    const caCert = await x509.X509CertificateGenerator.createSelfSigned({
        keys: caKeys,
        name: "CN=My CA",
        notBefore: new Date(),
        notAfter: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000), // 1 year validity
        signingAlgorithm: caAlg,
        extensions: [
            new x509.KeyUsagesExtension(x509.KeyUsageFlags.keyCertSign | x509.KeyUsageFlags.cRLSign, true),
            new x509.BasicConstraintsExtension(true, 2, true),
            await x509.SubjectKeyIdentifierExtension.create(caKeys.publicKey),
            await x509.AuthorityKeyIdentifierExtension.create(caKeys.publicKey)
        ]
    });
    console.log(caCert.toString("pem"));
  2. Read and Parse the CSR:

    const csrPem = fs.readFileSync("/path/to/your.csr", "utf-8");
    const csr = new x509.Pkcs10CertificateRequest(csrPem);
  3. Generate a Certificate from the CSR:

    const devCert = new x509.X509Certificate(fs.readFileSync("/path/to/your.ca.cer"));
    const ignoreExtensions = ["2.5.29.14", "2.5.29.35", "1.3.6.1.5.5.7.1.1"];
    
    const serviceCert = await x509.X509CertificateGenerator.create({
        publicKey: csr.publicKey,
        signingKey: caKeys.privateKey,
        issuer: devCert.subject,
        subject: csr.subject,
        notBefore: new Date(),
        notAfter: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000), // 1 year validity
        extensions: [
            ...csr.extensions.filter(o => !ignoreExtensions.includes(o.type)),
            await x509.SubjectKeyIdentifierExtension.create(csr.publicKey),
            await x509.AuthorityKeyIdentifierExtension.create(caKeys.publicKey)
        ]
    });
    console.log(serviceCert.toString("pem"));

This process allows you to create a new CA, generate a CSR, and then create a service certificate from both.

@BrianOpteran
Copy link
Author

@microshine Thank-you so much for this example. This has helped me fully implement what I needed. I had been close, but I don't think I'd have got there without your last example snippet here. Thanks so much for taking the time to put that together, I really appreciate it.

🙏🏼

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants