DEV Community

Sugumar Prabhakar
Sugumar Prabhakar

Posted on

1

Self Signed RSA Certificate with .NET 7

Asymmetric encryption uses a public/private key pair to encrypt the data at one end and decrypt the data on the other end. Most of the times, the encryption keys are created in the form of certificates, which might have been created in advance.

But for some scenarios such as IOT, certificates should be created for each device beforehand, which should be registered on the public cloud provider before using the IoT features. It will be tricky to create certificates beforehand if we have millions of devices to work with IoT and goes for production.

In this case, we can create our own self-signed device certificates at runtime using RSA in .NET Core

I'm gonna create a console application that will create a random RSA certificate and export the certificate and its private and public keys locally.

To do that, I'm gonna create a Console App project in VS2022.

Choosing Console App

Choosing .NET 7 as a framework

Choosing .NET7

Now the project has been created.
Let's create a public record model that will store the certificate instance as well as its keys.


 record CertificateModel(X509Certificate2 Certificate, string PublicKeyPEM, string PrivateKeyPEM, string PublicKeyPFX = "");

Enter fullscreen mode Exit fullscreen mode

Next, I'm gonna create a helper class to create RSA certificates and store its keys in a CertificateModel instance




internal class RSAHelper
{
    /// <summary>
    ///     Create a random RSA certificate for asymentric encryption
    /// </summary>
    /// <param name="subjectName">Subject name for the certificate. Ex, "cn=test"</param>
    /// <param name="hashAlgorithmName">Algorithm mode for creating hash keys</param>
    /// <param name="signaturePadding">Padding mode for the certificate signature</param>
    /// <returns>Certificate model</returns>
    public CertificateModel CreateRSACertificate(string subjectName
        , HashAlgorithmName hashAlgorithmName
        , RSASignaturePadding signaturePadding)
    {
        using var rsa = RSA.Create();
        var certRequest = new CertificateRequest(subjectName, rsa, hashAlgorithmName, signaturePadding);
        var certificate = certRequest.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddDays(1));

        var privateKey = Convert.ToBase64String(rsa.ExportRSAPrivateKey(), Base64FormattingOptions.InsertLineBreaks);
        var publicKey = certificate.ExportCertificatePem();
        var publicKeyPfx = Convert.ToBase64String(certificate.Export(X509ContentType.Pfx), Base64FormattingOptions.InsertLineBreaks);

        return new CertificateModel(certificate, publicKey, privateKey, publicKeyPfx);
    }
}



Enter fullscreen mode Exit fullscreen mode

That's it. The method "CreateRSACertificate" will create random RSA Keys and create a self-signed X509Certificate2 instance using the RSA keys which we created. It exports the private key and public key in a PEM format and stores it in the CertificateModel instance which will be returned to the caller method.

Now, we have to call RSAHelper.CreateRSACertificate() instance from the Program.cs class.



RSAHelper rsaHelperInstance = new RSAHelper();

Console.Write("Enter the subject name of the certificate : ");
var subjectName = $"CN={Console.ReadLine()?.ToUpper()}";

CertificateModel certificate = rsaHelperInstance.CreateRSACertificate(subjectName: subjectName
    , hashAlgorithmName: HashAlgorithmName.SHA256
    , signaturePadding: RSASignaturePadding.Pkcs1);

Console.WriteLine("Certificate is ready !!");
Console.Write("Do you want to save it locally? Press y or n : ");

char choice = Console.ReadKey().KeyChar;

if (choice == 'y')
{
    if (!Directory.Exists("Certificates"))
        Directory.CreateDirectory("Certificates");

    File.WriteAllText("Certificates/certificate.pem", certificate.PublicKeyPEM);
    File.WriteAllText("Certificates/certificate.private.pem", certificate.PrivateKeyPEM);
    File.WriteAllText("Certificates/certificate.pfx", certificate.PublicKeyPFX);

    Console.WriteLine();
    string filesLocation = Path.Combine(Directory.GetParent(Assembly.GetExecutingAssembly().Location)?.FullName ?? "", "Certificates");
    Console.WriteLine($"Files are saved in {filesLocation}");

    Process.Start(fileName: "explorer.exe", arguments: filesLocation);
}




Enter fullscreen mode Exit fullscreen mode

Here, I'm getting the subject name for the certificate from the user and passing it to the CreateRSACertificate() method which returns the CertificateModel Instance. Based on the user's interest, I'm saving the certificates and keys in a local file.

We can also save the certificates in X509Stores for appropriate usage.

_

Full source code is available here "RSACertificateGenerator.NET7"
_

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay