SgDotNet
Singapore Professional .NET User Group -For Cool Developers

Practical: XML digital signatures for application licensing

rated by 0 users
This post has 2 Replies | 0 Followers

Top 10 Contributor
Posts 2,284
icelava Posted: 01-12-2005 2:06 AM
Point of origin: http://www.codeproject.com/dotnet/xmldsiglic.asp

Has anybody ever thought about writing their own software components, or even programs, and want to sell them off the Internet? One of the most crucial points of development would then be how to effectively cripple the ability of users from passing copies of your component around with ease.

This is where digital signatures come into play to concretely enforce your license policies. I have previously toyed with this many months back but hit an error in recognising the key while getting the demo to work, and never got back to it again as i busied myself with other aspects.

I would very much like to restart this technical exercise once again. Even if it doesn't turn out to be a viable business option, at least getting it to work is a very good finish, a stepping stone to more complicated cryptography and licensing techniques.

The platform requirements for this is little: just the source demos from the article and experiment away on your PC (VS.NET will come in handy)! I prefer nearing end of this January, or beginning February as I have reservist mid-February.

The melody of logic will always play out the truth. ~ Narumi Ayumu, Spiral

Top 10 Contributor
Posts 2,284
Btw for those who subscribe to MSDN Magazine, the recent Nov-Dec issue features an article about XML encryption. Could well be highly relevant to this case, but I haven't gone through it to give a valid judgement. Do so later, or if anybody already read it, please comment.

The melody of logic will always play out the truth. ~ Narumi Ayumu, Spiral

Top 25 Contributor
Posts 232

I was trying to tackle this issue in my last job using Delphi accessing the Windows Crypto API provided by Microsoft and the final result was a disaster. My boss didn't like my asnwer. I quitted my job shortly after that.

Now with C# and the powerful .NET library, it's time to give it one more shot.

By the way, I read the article published on CodeProject and downloaded their source code to toy with. Like you, I ran into so many problems and eventually jump back to MSDN for more reading. Oh well, I can't complain even though I can't make their codes work as it's claimed. I have to give the author full credit for doing a good job in explaining the article.

After many hours of reading and so much more to read, I at least came up with a working sample:

using System;
using System.Xml;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;

namespace Test
{
  public class XmlSigning
  {
    public XmlSigning() {}
   
    private XmlDocument CreateDocument()
    {
      // CreateDocument creates 2 xml nodes to be signed: key and expire
   
      XmlDocument XmlDoc = new XmlDocument();
      XmlNode Node = XmlDoc.CreateElement("license");
      XmlDoc.AppendChild(Node);
     
      Node = XmlDoc.CreateElement("key");
      Node.InnerText = "1w5t00kg7~\\??><M.";
      XmlDoc.DocumentElement.AppendChild(Node);
     
      Node = XmlDoc.CreateElement("expire");
      Node.InnerText = "1/1/5000";
      XmlDoc.DocumentElement.AppendChild(Node);
               
      return XmlDoc;     
    }
   
    private void SignXmlDocument(RSA Key, XmlDocument XmlDoc)
    {
      SignedXml sxml = new SignedXml(XmlDoc);
      sxml.SigningKey = Key;
     
      // Canonicalization removes white space and formatting
      sxml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigCanonicalizationUrl;
     
      // Create a reference for packaging everything into the message.
      Reference r = new Reference("");
     
      // A signature transformation is applied to encrypt the hash
      r.AddTransform(new XmlDsigEnvelopedSignatureTransform(false));
     
      sxml.AddReference(r);
     
      sxml.ComputeSignature();
     
      // Get the xml representation of the signature
      XmlElement Signature = sxml.GetXml();
     
      XmlDoc.DocumentElement.AppendChild(Signature);          
    }
   
    private bool VerifyXmlDocument(RSA Key, XmlDocument XmlDoc)
    {
      SignedXml sxml = new SignedXml(XmlDoc);
     
      // I need to read more about this
      XmlNode Signature = XmlDoc.GetElementsByTagName("Signature",
        SignedXml.XmlDsigNamespaceUrl)[0];
     
      sxml.LoadXml((XmlElement) Signature);
      if (sxml.CheckSignature(Key))
      {
        return true;
      }
      else
      {
        return false;
      }     
    }
   
    public void DigitizeXml()
    {
      RSA Key = RSA.Create();
     
      XmlDocument XmlDoc = CreateDocument();
     
      SignXmlDocument(Key, XmlDoc);
     
      XmlDoc.Save("Signature.xml");
     
      // Verify the signature on our XML Document is good
      if (VerifyXmlDocument(Key, XmlDoc))
      {
        Console.WriteLine("OK");
      }
      else
      {
        Console.WriteLine("BAD SIGNATURE");
      }
     
     
      // Get the key node from the xml file. Change the value of the key node  
      XmlNode XmlNode = XmlDoc.GetElementsByTagName("key")[0];
      XmlNode.InnerText = "1w5t00kg7~\\??><M";
     
      // Get the expire node from the xml file. Change the value of the expire node 
      //XmlNode XmlNode = XmlDoc.GetElementsByTagName("expire")[0];
      //XmlNode.InnerText = "2/1/5000";
     
      // Now the signature check should fail
      if (VerifyXmlDocument(Key, XmlDoc))
      {
        Console.WriteLine("OK");
      }
      else
      {
        Console.WriteLine("BAD SIGNATURE");
      }     
    }
  }
 
  public class Test
  {
    public static void Main(string[] args)
    {
      XmlSigning ds = new XmlSigning();
      ds.DigitizeXml();      
    }
  } 
}

Below is a list of points implemented differently from the CodeProject article:

1. I removed the code to generate the key and machine code because it causes so many problems
2. I put everything into one single file for posting in here, not seperating them into 3 different files: ExtractPubKey.cs, Sign.cs and Verify.cs
3. I believe the code posted in here is a little easier to follow and understand. 
4. I still don't have a clear idea which is the best way to control license. a revisit of this issue is required until I have a better understanding
5. Expiry date is not yet implemented

Oh well, that's all for now.

Hope it helps

Page 1 of 1 (3 items) | RSS
Copyright SgDotNet 2004-2008
Powered by Community Server (Commercial Edition), by Telligent Systems