beaucrawford.net

Give me data or give me death

About the author

Author Name is someone.
E-mail me Send mail

Recent comments

Don't show

Authors

Tags

Don't show

    Disclaimer

    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

    © Copyright 2010

    Digitally Signing Business Objects

    I’m in the process of working on a Smart Client application that works with Business Objects.  All Business Objects implement the following interface:

    public interface IBusinessObject
    {
        int ID { get; }
        byte[] Signature { get; set; }
        byte[] ConcurrencyCheck { get; }
    
        // Other properties here
    }

    As you can see, each BO has a unique ID integer associated with it.  This value is used for many things. I want to ensure that a malicious user can not modify this value and present the hacked BO to the server.  To verify the integrity of the BO I decided to digitally sign it using the value of the ID property.  This can be done with the following code:

    public static void Sign(IBusinessObject instance)
    {
        Sign(instance, instance.ID);
    }
    
    public static void Sign(IBusinessObject instance, int id)
    {
        if (instance == null)
            throw new ArgumentNullException("instance");
    
        SHA1 sha = new SHA1CryptoServiceProvider();
        byte[] hash = sha.ComputeHash(BitConverter.GetBytes(id));
        DSASignatureFormatter DSAFormatter = new DSASignatureFormatter(DSAProvider);
        DSAFormatter.SetHashAlgorithm("SHA1");
        instance.Signature = DSAFormatter.CreateSignature(hash);
    }
    
    public const int ExpectedSignatureLength = 40;
    
    public static bool IsValid(IBusinessObject instance)
    {
        if (instance == null)
            throw new ArgumentNullException("instance");
    
        if (instance.Signature == null || instance.Signature.Length != ExpectedSignatureLength)
            return false;
    
        SHA1 sha = new SHA1CryptoServiceProvider();
        byte[] hash = sha.ComputeHash(BitConverter.GetBytes(instance.ID));
        DSASignatureDeformatter DSADeformatter = new DSASignatureDeformatter(DSAProvider);
        return DSADeformatter.VerifySignature(hash, instance.Signature);
    }

    The nice thing is that the DSASignatureFormatter class will automatically salt the generated signature.  It is important to note that the “DSAProvider” variable above be a static variable within the class.  This is needed in order to ensure that it is loaded with a constant key value so that, when a BO is verified at some point in the future, the check will succeed for previously issued signatures.  I accomplish this by loading the key using the “FromXmlString” method in the static constructor for the host class:

    public static readonly DSACryptoServiceProvider DSAProvider;
    
    static SecurityHelper()
    {
        DSAProvider = new DSACryptoServiceProvider();
        DSAProvider.FromXmlString(KeySet);  // Value obtained from ToXmlString
    }

    Categories: C#
    Posted by Beau on Sunday, August 24, 2008 1:29 PM
    Permalink | Comments (0) | Post RSSRSS comment feed

    Comments