Thursday, June 2, 2011

Creating SSL Certificates using OpenSSL.NET.

If you are using OpenSSL.NET to create SSL certificate programmatically and don't know where to start this article might help you.
First of all what is OpenSSL? OpenSSL is a cryptographic toolkit which is used to secure communication over web. OpenSSL provides a rich set of command line tools to create and manage SSL certificates.
But if you want to do it programmatically, then .NET provides a small but usefull wrapper for OpenSSL that is known as OpenSSL.NET.


Now without wasting much of your time, I will show you how to create a SSL X509 certificate using OpenSSL.NET.
First of all you must download OpenSSL.NET. Once you have downloaded it, you will see three dll files in the package i.e.  ManagedOpenSsl.dll, ssleay32.dll and libeay32.dll.

Before starting, make sure that you have added the refference to ManagedOpenSsl.dll in your project in visiual studio and  ssleay32.dll and libeay32.dll are available in the your current working directory or in your path.

Now we are done with setting up OpenSSL.NET and here is the code to create the SSL certificates.

###################################################
// Create a configuration object using openssl.cnf file.
OpenSSL.X509.Configuration cfg = new OpenSSL.X509.Configuration("Path to your openssl configuration file i.e. openssl.cnf");


// Create a root certificate authority which will have a self signed certificate.
OpenSSL.X509.X509CertificateAuthority RootCA = OpenSSL.X509.X509CertificateAuthority.SelfSigned(cfg, new SimpleSerialNumber(),"Disinguish name for your CA", DateTime.
Now, TimeSpan.FromDays(365));


// If you want the certificate of your root CA which you just create, you can get the certificate like this.
X509Certificate RootCertificate = rootCA.certificate;


// Here you need CSR(Certificate Signing Request) which you might have already got it from your web server e.g. IIS7.0.How to generate CSR on IIS 7.0


string strCSR = System.IO.File.ReadAllText(@"Path to your CSR file");

// You need to write the CSR string to a BIO object as shown below.
OpenSSL.Core.BIO ReqBIO = OpenSSL.Core.BIO.MemoryBuffer();
ReqBIO.Write(strCSR);


// Now you can create X509Rquest object using the ReqBIO.
OpenSSL.X509.X509Request Request = new OpenSSL.X509.X509Request(reqBIO);


// Once you have a request object, you can create a SSL Certificate which is signed by the self signed RootCA.
OpenSSL.X509.X509Certificate certificate = RootCA.ProcessRequest(Request, DateTime.Now, DateTime.Now + TimeSpan.FromDays(365));


// Now you can save this certificate to your file system.
FileStream fs = new FileStream("Path to your file where you want to create the certificate with file name", FileMode.Create, FileAccess.ReadWrite);
BinaryWriter bw = new BinaryWriter(fs);
BIO bio = BIO.MemoryBuffer();

certificate.Write(bio);
string certString = bio.ReadString();
bw.Write(certString);

##############################################

Finally make sure that you close all you BIO objects and File streams.

Now you have a X509 Certificate and you install it in your web server.

Hope this is helpful. Please provide your valuable comments and suggestions to improve my posts.

8 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. Is there a way to create the CSR file itself using OpenSSL.NET. To be precise, how would you equally do the following with it:

    openssl req -newkey rsa:2048 -keyout example.key -out example.csr
    -subj "/countryName=SE/organizationName=MyOwnCompany
    /organizationalUnitName=IT department/serialNumber=SE1122334455/
    commonName=Eximpexp"

    ReplyDelete
    Replies
    1. Sorry for my late reply.
      Yes, we can do this using X509Name and RSA key.

      X509Name DN = new X509Name();
      DN.Common = "Eximpexp";
      DN.Organization = "MyOwnCompany";
      DN.OrganizationUnit = "SE1122334455";
      DN.Country = "SE";

      RSA rsaKey = new RSA();
      ClientRSA.GenerateKeys(1024, 0x10021, null, null);
      CryptoKey ClientKey = new CryptoKey(rsaKey);

      then we can use it to create CSR(i.e. request object)-

      X509Request CSR = new X509Request(1, DN, rsaKey);

      Delete
  3. I save RootCA(certificate and PrivateKey) to folder. I want to sign more than one clients certificates. How can I load this RootCA(certificate and PrivateKey) from my folder and sign them?

    ReplyDelete
    Replies
    1. You can try something like this. Hope it will help you.

      BIO bio;
      bio = BIO.MemoryBuffer();

      byte[] rootcert = System.IO.File.ReadAllBytes("your root certificate");

      bio.Write(rootcert);

      X509Certificate rootCert = X509Certificate.FromDER(bio);

      bio.SetClose(BIO.CloseOption.Close);
      bio = BIO.MemoryBuffer();

      byte[] rootKey = System.IO.File.ReadAllBytes("your key");
      bio.Write(rootKey);

      Delete
    2. Code above not completed?

      For ProccessRequest we need X509CertificateAuthority
      How it can be obtained from BIO?

      Delete
  4. Hello!

    I need to create certificate using instructions:
    openssl req -config openssl.cfg -new -newkey rsa:2048 -days 1000 -keyout client_1.key -out client_1.csr
    openssl ca -config ca.cfg -days 1000 -policy policy_anything -keyfile ca.key -cert ca.crt -in client.csr -out client_1.crt
    openssl pkcs12 -export -inkey client.key -in client_1.crt -out client_1.pfx

    What I have to chenge in your code examle, so I could create my sertificate, like in those instructions?

    ReplyDelete
  5. Hi.. I have to sign and encrypt file using OpenSSL .net wraper. Can you please provide me example.

    ReplyDelete