Martin Mulder
Martin Mulder

Reputation: 12944

Creating PEM certificates in .NET Framework 4.8

I need to create a certificate from a .CER en .KEY file. I have a piece of working code in .NET 5, but this code needs to be converted to .NET Framework 4.8. Then method CreateFromPemFile does not exist in .NET Framework 4.8, so I need something else. I have already tried libraries like BouncyCastle, but somehow I keep getting exceptions. I even tried ChatGPT, but no luck yet.

static public X509Certificate2 CreateCertificate(string certificatePath, string keyPath)
{
    return new X509Certificate2(
        X509Certificate2.CreateFromPemFile(certificatePath, keyPath)
        .Export(X509ContentType.Pfx));
}

Maybe obvious, maybe neeeded:

The cer-file starts with: -----BEGIN CERTIFICATE-----

The key-file starts with: -----BEGIN PRIVATE KEY-----

Upvotes: 1

Views: 2023

Answers (1)

Martin Mulder
Martin Mulder

Reputation: 12944

After a lot of reading, trying, and asking chatGPT, I came up with the following solution, using BouncyCastle. This works for me. Maybe it helps others:

using System.IO;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Pkcs;

namespace Turien.Relations.TestConsole
{
    using X509Certificate2 = System.Security.Cryptography.X509Certificates.X509Certificate2;

    static class CertificateUtilities
    {
        static public X509Certificate2 CreateCertificate(string certificatePath, string keyPath)
        {
            var certParser = new Org.BouncyCastle.X509.X509CertificateParser();
            var cert = certParser.ReadCertificate(File.ReadAllBytes(certificatePath));

            AsymmetricCipherKeyPair keyPair;
            using (var reader = new StreamReader(keyPath))
            {
                var pemReader = new PemReader(reader);
                var rsaParams = (RsaPrivateCrtKeyParameters)pemReader.ReadObject();
                var rsaPubParams = new RsaKeyParameters(false, rsaParams.Modulus, rsaParams.PublicExponent);
                keyPair = new AsymmetricCipherKeyPair(rsaPubParams, rsaParams);
            }

            var store = new Pkcs12Store();
            var certEntry = new X509CertificateEntry(cert);
            store.SetCertificateEntry(cert.SubjectDN.ToString(), certEntry);
            store.SetKeyEntry(cert.SubjectDN.ToString(), new AsymmetricKeyEntry(keyPair.Private), new[] { certEntry });

            using (var stream = new MemoryStream())
            {
                store.Save(stream, null, new Org.BouncyCastle.Security.SecureRandom());
                return new X509Certificate2(stream.ToArray());
            }
        }
    }
}

Upvotes: 1

Related Questions