Using .pfx and .cer for security in .Net
Tags: csharp, dotnet, security
Published: 2019-01-14 05:51:20

---
title: Using .pfx and .cer for security in .Net
published: true
description: How to use pfx and cer files for safe encryption and decryption in .net. This can be used in your Web API as well. I have also referred to Bouncy Castle for this
tags: #csharp, #dotnet, #security
---

Security has become an integral part of our lives. We first tend to check with the security in our phone, in our home, in bank accounts and what not. The same has happened with the softwares.

Security has been a major point to mull over for any software development. To implement any security in an application, there are a lot of ways one can do that. One of the most common terms that one sees in this is “Cryptography”. According to wiki “Cryptography or cryptology is the practice and study of techniques for secure communication”. This practice of secure communication, can be achieved by a no of ways or algorithms. One of the basic thing to be implemented in crypto is encryption.

In cryptography, encryption is the process of encoding a message or information in such a way that only authorized parties can access it. Encryption does not itself prevent interference, but denies the intelligible content to a would-be interceptor. There are many algorithms present using which this can be done. One of the way to do that is using certificated and public and private keys.

Let me explain the two file formats we will see here. [Link](https://stackoverflow.com/questions/2292495/what-is-the-difference-between-a-cer-pvk-and-pfx-file)

## What is PFX ?

In cryptography, PKCS #12 defines an archive file format(.p12 or .pfx) for storing many cryptography objects as a single file. It is commonly used to bundle a private key with its X.509 certificate or to bundle all the members of a chain of trust. Windows uses .pfx for a PKCS #12 file. This file can contain a variety of cryptographic information, including certificates, certificate chains, root authority certificates, and private keys. Its contents can be cryptographically protected (with passwords) to keep private keys private and preserve the integrity of root certificates.

## What is CER ?

Windows uses .cer extension for an X.509 certificate. These can be in “binary” (ASN.1 DER), or it can be encoded with Base-64 and have a header and footer applied (PEM); Windows will recognize either. To verify the integrity of a certificate, you have to check its signature using the issuer’s public key… which is, in turn, another certificate.

## Using pfx and cer in .Net application
I have been using these files for encryption and decryption of the data in a few web services. The pfx and vcer file can be generated using the utilities in the Windows operating systems. However, it becomes really great if there is someway, where we can automate this programatically.

To do this, I am using an [API Bouncy Castle](https://www.bouncycastle.org/). It is simply an amazing work by these guys here.

In C#, I have created a console app, and installed bouncy castle in the project. To install the nuget package, use [Install-Package BouncyCastle -Version 1.8.1](https://www.nuget.org/packages/BouncyCastle/)

Once this is installed, you can use the following code to create a pfx file.

```
using Data.Helpers;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Operators;
using Org.BouncyCastle.Crypto.Prng;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using System;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;

namespace CreateKeyHolders
{
 public static class CertificateBuilder
 {
 /// <summary>
 /// Creates the certificate based on the subject name
 /// </summary>
 /// <param name="certificate">The certificate object with custom values for the certificate</param>
 /// <returns></returns>
 public static bool GeneratePfx(CertificateAttributes certificate)
 {
 var isCertificateCreated = false;
 try
 {
 var keyPairGenerator = new RsaKeyPairGenerator();
 keyPairGenerator.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 1024));
 var kp = keyPairGenerator.GenerateKeyPair();
 var signatureFactory = new Asn1SignatureFactory(certificate.Algorithm.GetDescription(), kp.Private);
 var gen = new X509V3CertificateGenerator();
 var certName = new X509Name("CN=" + certificate.SubjectName);
 var serialNo = BigInteger.ProbablePrime(120, new Random());
 //sets the serial no for the certificate : add a custom serial no if you have one
 gen.SetSerialNumber(serialNo);
 //set the subject name : can be custom here
 gen.SetSubjectDN(certName);
 //sets the issuer name
 gen.SetIssuerDN(certName);
 gen.SetNotAfter(DateTime.Now.AddYears(100));
 gen.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0)));
 //set the public key for the certificate
 gen.SetPublicKey(kp.Public);

gen.AddExtension(
 X509Extensions.AuthorityKeyIdentifier.Id,
 false,
 new AuthorityKeyIdentifier(
 SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(kp.Public),
 new GeneralNames(new GeneralName(certName)),
 serialNo));

gen.AddExtension(
 X509Extensions.ExtendedKeyUsage.Id,
 false,
 new ExtendedKeyUsage(new List { new DerObjectIdentifier("1.3.6.1.5.5.7.3.1") }));

var newCert = gen.Generate(signatureFactory);
 var createdCertificate = DotNetUtilities.ToX509Certificate(newCert);
 var byteArray = createdCertificate.Export(X509ContentType.Pkcs12, certificate.Password);
 var byteArray1 = createdCertificate.Export(X509ContentType.Cert, certificate.Password);

//Save the pfx file here
 Helper.WriteAllBytes("C:\\certs\\" + certificate.SubjectName + ".pfx", byteArray);

//save the cert here
 if (certificate.SaveCerFile)
 Helper.WriteAllBytes("C:\\certs\\" + certificate.SubjectName + ".cer", byteArray1);

isCertificateCreated = true;
 }
 catch (Exception exception)
 {
 var logger = new Logger.FileLogger();
 logger.Log(exception);
 }

return isCertificateCreated;
 }
 }
}
```

The properties of the certificate like subject name, issuer name, serial nos. are the ones that defines a certificate. Please use these values quite meticulously.

The usage of this code would be :

```
var result = CertificateBuilder.GeneratePfx("appCert", "passowrd");

```

This will create a pfx file and a cer file by the name appcert and the password mentioned in the parameter. We can now use these created files in our application for encryption and decryption of the data.

We will now see how to use these files for implementing security.

You may use or modify the following code for this:

```
class Program
 {
 static void Main()
 {
 //var result = CertificateBuilder.GeneratePfx("test", "test@1234");

const string DecryptCertPath = @"E:\.pfx";
 const string EncryptCertPath = @"E:\.cer";

const string input = "The quick brown fox jumps over a lazy dog.";
 var array = Helper.GetBytes(input);
 var ecertificate2 = ReadPfx.GetCertificate(EncryptCertPath);
 var encrypted = Encrypt.EncryptData(array, ecertificate2);
 var encryptedbase64 = Convert.ToBase64String(encrypted);
 Console.WriteLine(encryptedbase64);
 var decryptedArray = Convert.FromBase64String(encryptedbase64);
 var dcertificate2 = ReadPfx.GetCertificate(DecryptCertPath);
 var decrypted = Decrypt.DecryptData(encrypted, dcertificate2);
 var decryptedString = Helper.GetStringFromByte(decrypted);
 Console.WriteLine(Environment.NewLine);
 Console.WriteLine(decryptedString);
 Console.WriteLine("==================================================");
 Console.ReadKey();
 }
 }

```