Convert RSA public key from XML to PEM format (.NET) (Part 1)

Probably the people working with asymmetric cryptography have struggled for a way to convert the XML format of the RSA public key to the more widely used PEM format. Although there is a solution for the reverse transformation (from PEM to XML) on the following address http://www.jensign.com/opensslkey/opensslkey.cs I have not found anywhere a solution to this problem.

So after a bit of reading and examining the code in the above mentioned link I’ve come up with a small code that does the conversion and the resulting key is parsed OK from OpenSSL.

NOTE: You will need to download and use the assemblies from http://clrsecurity.codeplex.com/
NOTE2: The code bellow only works under Windows 7 and Windows Server 2008 R2, because it uses the Cryptographic Next Generation (CNG) that were added only to those operating systems.

C#:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            RSACng rsa = new RSACng();
            X509Certificate2 cert;
            List<byte> arrBinaryPublicKey = new List<byte>();

            byte[] oid = 
            { 0x30, 0xD, 0x6, 0x9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0xD, 0x1, 0x1, 0x1, 0x5, 0x0 }; // Object ID for RSA

            //rsa.FromXmlString(xmlFormatedRSAKey);

            cert = rsa.Key.CreateSelfSignedCertificate(new X500DistinguishedName("CN=something"));

            //Transform the public key to PEM Base64 Format
            arrBinaryPublicKey = cert.PublicKey.EncodedKeyValue.RawData.ToList();
            arrBinaryPublicKey.Insert(0, 0x0); // Add NULL value

            CalculateAndAppendLength(ref arrBinaryPublicKey);

            arrBinaryPublicKey.Insert(0, 0x3);
            arrBinaryPublicKey.InsertRange(0, oid);

            CalculateAndAppendLength(ref arrBinaryPublicKey);

            arrBinaryPublicKey.Insert(0, 0x30);
            //End Transformation

            Console.WriteLine();
            Console.WriteLine("-----BEGIN PUBLIC KEY-----");
            Console.WriteLine(System.Convert.ToBase64String(arrBinaryPublicKey.ToArray()));
            Console.WriteLine("-----END PUBLIC KEY-----");

        }

        private static void CalculateAndAppendLength(ref List<byte> arrBinaryData)
        {
            int nLen;
            nLen = arrBinaryData.Count;
            if (nLen <= byte.MaxValue)
            {
                arrBinaryData.Insert(0, Convert.ToByte(nLen));
                arrBinaryData.Insert(0, 0x81); //This byte means that the length fits in one byte
            }
            else
            {
                arrBinaryData.Insert(0, Convert.ToByte(nLen % (byte.MaxValue + 1)));
                arrBinaryData.Insert(0, Convert.ToByte(nLen / (byte.MaxValue + 1)));
                arrBinaryData.Insert(0, 0x82); //This byte means that the length fits in two byte
            }

        }

    }
}

Compiled source available here

5 replies
  1. Maple Leafs
    Maple Leafs says:

    First of all I thank you for your contribution to address this issue. The thing is that I couldn't compile the code you placed. Can you post the compile source of your program? I've been looking for hours a solution to transform the xml rsa file into pem and it appears that you are the only one that has been able to solve it.

    Thank you in advanced.

    Christian Troncoso
    Software Engineer

    Reply
  2. Peter Staev
    Peter Staev says:

    Hi Christian,

    I've posted a link to the compiled source at the end of the main post. Please try it out, hope it helps.

    BTW, you probably did not download from codeplex the libraries mentioned in the post, just above the source code. That's why the source does not want to compile.

    Reply
  3. Maple Leafs
    Maple Leafs says:

    Dear Peter

    Thank you for your help. Your work really helped me out with the implementation of RSA Encription. Turns out that Ruby on Rails works using pem files and my aplication on VB in xml. I appretiate the help!

    Regards

    Christian Troncoso R.
    Software Engineer.

    Reply

Trackbacks & Pingbacks

  1. […] my previous post I’ve shown how to convert the public key of an XML formatted RSA key to the more widely used […]

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply to Maple Leafs Cancel reply

Your email address will not be published. Required fields are marked *