How to Use Digital Signatures in C#
    In some of my projects I had a need to create and verify licenses. I
      needed to be able to verify that the license was one that I had issued and
      had not been tampered with or modified. A digital signature was the
      natural way to implement this requirement. I did a bit of digging into the
      C# cryptographic APIs and learned that everything required to create and
      verify digital signatures was already provided.
    I am not going to go into a detailed explanation of how digital
      signatures work as there are many good references available on the
      subject. In this article I am going to focus on one specific
      implementation using C#. This example also does not include features such
      as revoking licenses or limiting the number of installations. This is just
      a bare bones example to demonstrate one possible solution.
    Creating a key pair
    Before I can sign anything I would need to generate a public/private key
      pair. The private key is for creating the digital signature. As its' name
      implies, this key must be stored securely and not shared. The public key
      is for verifying that the signature is valid and that the license has not
      been changed. I would need to embed the public key in my software so that
      the license could be verified at run time.
    In order to create a key pair we can use the RSACryptoServiceProvider
      class which is part of the System.Security.Cryptography library. This is a
      one time step as once we have generated the keys we only need to do it
      again if we require a new set of keys. The new keys won't work with any
      signatures we generated using a prior set of keys.
    The first step in generating the keys is to instantiate the class
        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
    This initializes a new instance of the RSA class with a randomly
      generated key pair. Now we need to retrieve the keys and save them. There
      are multiple ways to accomplish this. I chose to retrieve them as XML
      strings as I felt they were easy to work with in that format. The way to
      do that is to use the ToXmlString() method of the RSA class. Passing in a
      parameter of true includes the private key. A parameter of false gives us
      just the public key.
        string privateKey = rsa.ToXmlString(true);
    string publicKey = rsa.ToXmlString(false);
    Now that we have the keys we can save them however we wish. The simplest
      way is to write them to files on disk.
        string privateKeyPath = "private.key";
    string publicKeyPath = "public.key";
    File.WriteAllText(privateKeyPath, privateKey);
    File.WriteAllText(publicKeyPath, publicKey);
    Store the private key somewhere safe.
    Signing the data
    Now that we have the keys we can sign our data. One implementation would
      be to use a license terms class to hold whatever information about the
      license we care about. For this example I will just include the user's
      name and email address. In a real implementation you would probably need
      to include things like issue date, expiration date, the product, the
      license type, or maybe what application features are enabled by this
      license. Those items would be easy enough to add.
    
    [Serializable]
    public class LicenseTerms
    {
        public String UserName { get; set; }
        public string UserEmail { get; set; }
        public override string ToString()
        {
            StringBuilder builder = new StringBuilder();
            builder.Append(" UserName: " + this.UserName);
            builder.Append(" UserEmail: " + this.UserEmail);
            return builder.ToString();
        }
    }
    
    There are a couple of things worth noting. The first is that I declared
      this class as Serializable. The reason for this will be explained in a
      moment. The other is that I chose to over ride the ToString() method. This
      was done purely as a convenience for debugging. It becomes more useful if
      we later decide to add more fields to the license.
    In order to create a digital signature for the LicenseTerms class we will
      use the SignData() method of the RSA class we instantiated earlier. The
      only problem is that this method signs an array of bytes, not a
      LicenseTerms class. So now we need a way to convert the LicenseTerms to an
      array of bytes. We can accomplish this using serialization. That is the
      reason for declaring the LicenseTerms class as serializable. 
    Here's the method we need to add to the LicenseTerms class. It returns
      the class as a byte array.
        public byte[] GetLicenseData()
    {
        using (MemoryStream ms = new MemoryStream())
        {
            // create a binary formatter:
            BinaryFormatter bnfmt = new BinaryFormatter();
            // serialize the data to the memory-stream;
            bnfmt.Serialize(ms, this);
            // return a byte array representation of the binary data:
            return ms.GetBuffer();
        }
    }
    Now we have everything we need to sign the license terms. Here's the code
      to sign the license data. We need the private key in XML format and the
      license terms. We use the FromXmlString method of the RSA class to
      initialize it with our private key.
        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
    rsa.FromXmlString(privateKey);
    // get the byte-array of the license terms:
    byte[] license = terms.GetLicenseData();
    // get the signature:
    byte[] signature = rsa.SignData(license, new SHA1CryptoServiceProvider());
 
     
    Save the signature along with the license terms. One method would be to
      create a License class to hold the signature and the license terms. Then
      you can serialize the License class to a disk file. A sample License class
      would look something like the following class. You may choose to implement
      this differently depending on your requirements.
       [Serializable]
    public class License
    {
        public LicenseTerms LicenseTerms { get; set; }
        public byte[] Signature { get; set; }
    }    
    Verifying the signature 
    At run time we want to be able to verify that the license signature is
      valid. The RSA class provides the method VerifyData() to perform that
      check. We need to pass in the data that was signed as a byte array as well
      as the signature, also as a byte array. Since we saved the public key as
      XML we can use the FromXmlString() method of the RSA class to initialize
      it with our public key.
    
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
    rsa.FromXmlString(PublicKey);
    
    // get the license terms
    byte[] terms = licenseTerms.GetLicenseData());
    // use the signature we generated. If you were using the License class
    // you woul ddo something like this
    byte[] signature = license.Signature;
    if (rsa.VerifyData(terms, new SHA1CryptoServiceProvider(), signature))
    {
        Console.WriteLine("Signature is valid");
        Console.WriteLine("Terms: " + license.LicenseTerms);
    }
    else
    {
        Console.WriteLine("Signature is not a valid signature");
    }
    
    That completes this example. To sum up, we saw how to generate a
      public/private key pair, how to digitally sign something, and how to
      verify the signature. I hope you find this example instructive. Have fun
      coding!