Sample ASP.NET code written in C# that responds to a license request

protected void Page_Load(object sender, EventArgs e)
{
    // post parameters
    String compID = Request.Form["COMP_ID"]; // you may not receive this parameter if your license type is not Computer Specific
    String ID = Request.Form["ID"]; // this is the license ID that user entered into the Registration dialog.

    try
    {
        // Step 1 - Find the license with the specified ID in your database.

        // ...

        // Step 2 [IMPORTANT] - Decide if the license request is legit
        // make sure the license ID sent by the user (ID post value) is in your users database and only then continue generating a license for it
        if (false /*< invalid license request ... >*/)
        {
            SendResponse(500, "Invalid license ID.");
            return;
        }

        // Step 3 - Computing the license digital signature
        // if present, add extra license elements like MP and EXP maintaining the alphabetical order

        String data = "";
        if (compID != null)
            data += "COMP_ID=" + compID;

        data += "ID=" + ID;

        // data is now like 'COMP_ID=1283391946329685ID=john@example.com';


        // load the private key. You should obtain this key by exporting from the
        // Licensing > Registration page, by using the "Export PEM" Public - Private key pair action.
        // You must take safety measures to protect this key (like protecting it with a password) before you upload it to your server.
        string sPrivateKeyPEM = File.ReadAllText(Server.MapPath("~/licenseKey.pem"));
        RSACryptoServiceProvider rsaProvider = PEMToX509.GetRSA(sPrivateKeyPEM);

        if (rsaProvider == null)
        {
            SendResponse(501, "Keys generator setup failed");
            return;
        }

        // compute signature
        byte[] dataToSign = Encoding.Unicode.GetBytes(data);
        byte[] signature = rsaProvider.SignData(dataToSign, new SHA1CryptoServiceProvider());

        // Step 4 - Respond with the license elements
        // if your license has a Maintainance Plan element (or any other elements) add them in alphabetical order
        String responseData = "ID=" + ID + /* ";MP" + MP + */ ";SIGN=" + Convert.ToBase64String(signature);
        SendResponse(200, responseData);
    }
    catch
    {
        SendResponse(501, "Keys generator setup failed");
    }
}

private void SendResponse(int statusCode, String message)
{
    // Set response data
    Context.Response.Clear();
    Context.Response.StatusCode = statusCode;
    Context.Response.TrySkipIisCustomErrors = true;
    Context.Response.Write(message);

    // Complete current request
    Context.ApplicationInstance.CompleteRequest();
}

// Helper class for using pem key format
internal static class PEMToX509
{
    const string KEY_HEADER = "-----BEGIN RSA PRIVATE KEY-----";
    const string KEY_FOOTER = "-----END RSA PRIVATE KEY-----";

    internal static RSACryptoServiceProvider GetRSA(string pem)
    {
        RSACryptoServiceProvider rsa = null;

        if (IsPrivateKeyAvailable(pem))
        {

            string keyFormatted = pem;

            int cutIndex = keyFormatted.IndexOf(KEY_HEADER);
            keyFormatted = keyFormatted.Substring(cutIndex, keyFormatted.Length - cutIndex);
            cutIndex = keyFormatted.IndexOf(KEY_FOOTER);
            keyFormatted = keyFormatted.Substring(0, cutIndex + KEY_FOOTER.Length);
            keyFormatted = keyFormatted.Replace(KEY_HEADER, "");
            keyFormatted = keyFormatted.Replace(KEY_FOOTER, "");
            keyFormatted = keyFormatted.Replace("\r", "");
            keyFormatted = keyFormatted.Replace("\n", "");
            keyFormatted = keyFormatted.Trim();

            byte[] privateKeyInDER = System.Convert.FromBase64String(keyFormatted);

            rsa = DecodeRSAPrivateKey(privateKeyInDER);
        }

        return rsa;
    }

    private static bool IsPrivateKeyAvailable(string privateKeyInPEM)
    {
        return (privateKeyInPEM != null && privateKeyInPEM.Contains(KEY_HEADER)
            && privateKeyInPEM.Contains(KEY_FOOTER));
    }

    //------- Parses binary ans.1 RSA private key; returns RSACryptoServiceProvider  ---
    public static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
    {
        byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;

        // ---------  Set up stream to decode the asn.1 encoded RSA private key  ------
        MemoryStream mem = new MemoryStream(privkey);
        BinaryReader binr = new BinaryReader(mem);    //wrap Memory Stream with BinaryReader for easy reading
        byte bt = 0;
        ushort twobytes = 0;
        int elems = 0;
        try
        {
            twobytes = binr.ReadUInt16();
            if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
                binr.ReadByte();        //advance 1 byte
            else if (twobytes == 0x8230)
                binr.ReadInt16();       //advance 2 bytes
            else
                return null;

            twobytes = binr.ReadUInt16();
            if (twobytes != 0x0102) //version number
                return null;
            bt = binr.ReadByte();
            if (bt != 0x00)
                return null;


            //------  all private key components are Integer sequences ----
            elems = GetIntegerSize(binr);
            MODULUS = binr.ReadBytes(elems);

            elems = GetIntegerSize(binr);
            E = binr.ReadBytes(elems);

            elems = GetIntegerSize(binr);
            D = binr.ReadBytes(elems);

            elems = GetIntegerSize(binr);
            P = binr.ReadBytes(elems);

            elems = GetIntegerSize(binr);
            Q = binr.ReadBytes(elems);

            elems = GetIntegerSize(binr);
            DP = binr.ReadBytes(elems);

            elems = GetIntegerSize(binr);
            DQ = binr.ReadBytes(elems);

            elems = GetIntegerSize(binr);
            IQ = binr.ReadBytes(elems);

            // ------- create RSACryptoServiceProvider instance and initialize with private key -----
            RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
            RSAParameters RSAparams = new RSAParameters();
            RSAparams.Modulus = MODULUS;
            RSAparams.Exponent = E;
            RSAparams.D = D;
            RSAparams.P = P;
            RSAparams.Q = Q;
            RSAparams.DP = DP;
            RSAparams.DQ = DQ;
            RSAparams.InverseQ = IQ;
            RSA.ImportParameters(RSAparams);
            return RSA;
        }
        catch (Exception)
        {
            return null;
        }
        finally
        {
            binr.Close();
        }
    }

    private static int GetIntegerSize(BinaryReader binary)
    {
        byte bt = 0;
        byte lowbyte = 0x00;
        byte highbyte = 0x00;
        int count = 0;

        bt = binary.ReadByte();

        if (bt != 0x02)
            return 0;

        bt = binary.ReadByte();

        if (bt == 0x81)
            count = binary.ReadByte();
        else if (bt == 0x82)
        {
            highbyte = binary.ReadByte();
            lowbyte = binary.ReadByte();
            byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
            count = BitConverter.ToInt32(modint, 0);
        }
        else
            count = bt;

        while (binary.ReadByte() == 0x00)
            count -= 1;

        binary.BaseStream.Seek(-1, SeekOrigin.Current);

        return count;
    }
}