Wednesday, November 16, 2011

Encryption in C#

C# has a lot of good support for almost all modern cryptographic functions, but they are rarely easy to understand.  Most people are aware of the fact that encryption is meant to prevent data from being read/ used in an unauthorized manner, but that's usually as far as they want to take it.  Implementing encryption implies a certain level of complication, and writing it into your application can be a daunting prospect.  Hopefully this article will make things a bit more digestible.

There are three main types of encryption mechanisms: one-way, symmetric, and asymmetric.  They each have strengths and weaknesses, and are practical for different things. In this article I will explain one-way and symmetric; asymmetric is an article in itself.

One-way Encryption
One-way encryption is a bit of a misnomer; most people refer to these as hashes, or checksums.  It involves taking some data and deriving a digital "signature" from it - the same data will always produce the same signature.  The data cannot, however, be derived from the signature, and it is possible (though very rare, especially with modern hashing algorithms) that different data will produce the same signature.  This is called collision, and in some cases steps need to be taken to reduce the possibility of the same hash from being created.


It's called "one-way encryption" because the hashed data cannot be "unhashed"... the signature does not contain the original data.  There are quite a few advantages to this:
  1. Hashing is usually very fast compared to reversible encryption techniques.  On a small scale, this is not especially noticeable, but when dealing with large amounts of data, this can become rather significant.
  2. Due to its relative speed, hashing is useful for comparing large pieces of data with other large pieces of data.  Often, when used in this manner, a hash is called a checksum.  A good use case is verifying a large file successfully transferred over the network; the file publisher says the checksum should be X, and when you run the same checksum algorithm on your side, you should also get X... if you don't, there's a discrepancy that needs to be investigated.
  3. Hashing is also good if you don't want to be able to derive the original data, for security reasons.  For example, passwords are often stored in a database in hashed form.  When authenticating against a stored password hash, you would hash the password submitted by the user and compare the signatures; if they match, the user has authenticated.  (Note: if you care enough to hash your passwords, make sure you salt them first... out of scope for this article, but google salting passwords for a quick how-to)
  4. Hashes have a fixed length (the lengths are different depending on the algorithm used to hash, but the data has no bearing on the size of the hash), which makes them fit nicely into various strongly-typed storage containers.
In c#, it's pretty easy to write a simple hashing algorithm to suit your needs:


        public static byte[] GenerateHash(string toHash)
        {
            var bytes = Encoding.UTF8.GetBytes(toHash);
            using (var algorithm = new SHA384Managed())
            {
                return algorithm.ComputeHash(bytes);
            }
        }
In this case, you simply provide the string you wish to hash, and it generates a hash for you.  In this case, I chose to use the SHA-384 (a derivative of the SHA-2 algorithm) algorithm, as it's fairly fast and fairly secure.  I recommend against MD5, CRC, and SHA-1 because they tend to have some weaknesses (similar data may produce similar hashes, and that's generally not desired).

Symmetric Encryption
Symmetric encryption is a form of reversible encryption (i.e., the data can be decrypted and used) that uses a single encryption key to both encrypt and decrypt the data.  Whoever has the encryption key and knows how the data was encrypted can easily decrypt it.  Some things to remember about symmetric encryption:
  1. Symmetric encryption is usually significantly slower than hashing, but significantly faster than asymmetric encryption.
  2. Symmetric encryption is good if you can reasonably protect the encryption key, but the key needs to be available to all people who need to encrypt or decrypt the data.  You have to trust the data managers.
  3. Symmetrically encrypted data needs to be decrypted in the same manner it was encrypted in. It's kinda a no-brainer, but it means that your encryption method should be paired with your decryption method so you can keep your algorithms and settings properly synchronized.
  4. Since the actual data is contained in the encrypted payload, if your data is big, your encryption will also be big.
In c#, this is also fairly straightforward to implement.  The namespaces we will need are like so:
    using System;
    using System.IO;
    using System.Linq;
    using System.Security.Cryptography;
    using System.Text;

...and here's the code:

        public static byte[] EncryptString(string toEncrypt, byte[] encryptionKey)
        {
             var toEncryptBytes = Encoding.UTF8.GetBytes(toEncrypt);
            using (var provider = new AesCryptoServiceProvider())
            {
                provider.Key = encryptionKey;
                provider.Mode = CipherMode.CBC;
                provider.Padding = PaddingMode.PKCS7;
                using (var encryptor = provider.CreateEncryptor(provider.Key, provider.IV))
                {
                    using (var ms = new MemoryStream())
                    {
                        using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                        {
                            cs.Write(toEncryptBytes, 0, toEncryptBytes.Length);
                            cs.FlushFinalBlock();
                            var retVal = new byte[16 + ms.Length];
                            provider.IV.CopyTo(retVal, 0);
                            ms.ToArray().CopyTo(retVal, 16);
                            return retVal;
                        }
                    }
                }
            }
        }

        public static string DecryptString(byte[] encryptedString, byte[] encryptionKey)
        {
             using (var provider = new AesCryptoServiceProvider())
            {
                provider.Key = encryptionKey;
                provider.Mode = CipherMode.CBC;
                provider.Padding = PaddingMode.PKCS7;
                provider.IV = encryptedString.Take(16).ToArray();
                using (var ms = new MemoryStream(encryptedString, 16, encryptedString.Length - 16))
                {
                    using (var decryptor = provider.CreateDecryptor(provider.Key, provider.IV))
                    {
                        using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                        {
                            byte[] decrypted = new byte[encryptedString.Length];
                            var byteCount = cs.Read(decrypted, 0, encryptedString.Length);
                            return Encoding.UTF8.GetString(decrypted, 0, byteCount);
                        }
                    }
                }
            }
        }
A couple of things to note about the above code:
  1. It took me a while to wrap my brain around the IV (Initialization Vector).  Now I consider it similar to a salt value on a hash, because it's used for the same practical purpose (out of scope for this article), but just so I mention this a bit, with most symmetric encryption, the blocks of data you are encrypting build on data you had just finished encrypting, so the encrypted data will actually look different encoding similar data.  The IV actually "pretends" to be data you've already encrypted, and it's generally set randomly with each instantiation of the CryptoServiceProvider.  End result?  You can encrypt the same data with the same key a bunch of times, and the encrypted data payload will look different, but hold the same info.
  2. The IV is prepended to the actual payload of the data upon encryption, and stripped off before decryption.  This is a good practice, but not the only good practice.  A lot of people would want to save that separately.  I did it this way so I only have to pass the payload and key around.  Works pretty well.
  3. The mode I chose is a reasonably secure, as well as the padding; I primarily chose these because they were easy to test, and still secure.
That's it!  These methods can encrypt your data anywhere, without a lot of code.  If you want to save your data in string format you can use these functions for easy conversion:

     Convert.ToBase64String(byteArray);
     Convert.FromBase64String(string)

To generate a new encryption key for the above symmetric encryption functions, you can use something like this:

        public static byte[] GenerateAESKey()
        {
            using (var provider = new AesManaged())
            {
                provider.KeySize = 256;
                provider.GenerateKey();
                return provider.Key;
            }
        }

...and you should be good to go!













Tuesday, October 25, 2011

RequireHttps attribute and IIS Express

Perhaps you, like me, have been frustrated by the RequireHttpsAttribute functionality in MVC.  It's a great concept; an easy attribute class to force redirection to a secure channel, but it was kinda frustrating how it was implemented, especially since the advent of IIS Express.

If you didn't know, IIS Express is a great tool that integrates seamlessly into Visual Studio 2010.  It works very well, and you can enable HTTP over SSL with the click of a mouse.  I love it; there's only one problem: it assigns both the cleartext and the secure channel to unique TCP ports.  From IIS Express's perspective, this is a good thing, keeping everything nice and separate... from a development perspective, this is annoying, because we do not have the ability to tell our code which port to use when redirecting to the secure channel.

Well this cheesed me off enough that I decided to do something about it.  I liked the idea of an attribute class controlling the redirect; it kept my controllers clean from clutter; however, the IIS secure port is machine specific, and in production it's almost always going to be 443.  Attributes do not support variable arguments, so I had to get a little creative.  What I ended up with is this:


using System.Configuration;

namespace System.Web.Mvc
{
[AttributeUsage(AttributeTargets.Class)]
public class RedirectHttpsAttribute : ActionFilterAttribute
{
#region Properties
private static string _DisableHttpsRedirect;
/// <summary>
/// When true, forcing a redirect to a secure page is suppressed.
/// </summary>
/// <remarks>
/// This value can be set in the config file under the "DisableHttpsRedirect" app setting.
/// </remarks>
public static bool DisableHttpsRedirect
{
get
{
if (string.IsNullOrEmpty(_DisableHttpsRedirect))
{
_DisableHttpsRedirect = (ConfigurationManager.AppSettings["DisableHttpsRedirect"] ?? "False");
}

bool retValue;
if (!bool.TryParse(_DisableHttpsRedirect, out retValue))
{
retValue = false;
}

return retValue;
}

set
{
_DisableHttpsRedirect = value.ToString();
}

}

private static string _SecurePort;
/// <summary>
/// When set to a number, explicitly declares the port of the URL in the redirect string.
/// When set to -1, uses the default protocol port (no port number in the string)
/// </summary>
/// <remarks>
/// This value can be set in the config file under the "SecurePort" app setting.
/// </remarks>
public static int SecurePort
{
get
{
if (string.IsNullOrEmpty(_SecurePort))
{
_SecurePort = (ConfigurationManager.AppSettings["SecurePort"] ?? "-1");
}

int retValue;
if (!int.TryParse(_SecurePort, out retValue))
{
retValue = -1;
}

return retValue;
}

set
{
_SecurePort = value.ToString();
}
}
#endregion

public override void OnResultExecuting(ResultExecutingContext filterContext)
{

//Allow the redirect to be disabled in the config file.  This may be necessary for testing purposes.
if (!filterContext.HttpContext.Request.IsSecureConnection &&
!DisableHttpsRedirect)
{
//replace the contents of the nonsecure string with the proper protocol and port number.
UriBuilder ub = new UriBuilder(filterContext.HttpContext.Request.Url);
ub.Scheme = "https";
ub.Port = SecurePort;

//direct the context to redirect to the proper secure channel.
filterContext.Result = new RedirectResult(ub.ToString());
filterContext.Result.ExecuteResult(filterContext);
}

return;
}
}
}

This allows the HTTPS port to be configured in the web.config file as follows:

  • Setting: "DisableHttpsRedirect" this can be used on a dev machine with no access to SSL; shouldn't be necessary in most cases with IIS express, but it's possible.  The default value is "false".  Whenever you're forcing control of an application somewhere else, it's a good idea to expose a means to override the behavior for isolation purposes.
  • Setting: "SecurePort" this allows you to set the secure port number in your web.config file.  The default is -1 which the URL builder will take to mean the default port (in the case of HTTPS, that is 443)  This way, you can have your production environment run without a port number specifier, which would look goofy.

There!  All we have to do now is make an abstract Controller class tagged with the [RedirectHttps] attribute, have the rest of our controllers inherit from it and configure the joker in the web config.  Problem solved.

Wednesday, October 12, 2011

MVC3 Helper methods supporting Linq Expressions

I was a bit frustrated with the .DropDownFor() extension on the HtmlHelper class.  There was no access to the OPTION tags, and I've never been a fan of the SelectList object.  I wanted to put some tool tip text (using the title attribute) on the options to provide more context in the selection.  Of course there was no way to do that with the .DropDownFor() helper method.  So, time to roll my own.

Only thing was, I'd never written an extension that used a Linq expression before, so it took a little research.  Finally I found this post (I heart StackOverflow) and piecing it together from there, came up with this joker:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web;


namespace System.Web.Mvc
{
public static class MoreHelpers
{
public static HtmlString SelectFor<TModel, TProperty, TListItem>(
this HtmlHelper<TModel> htmlHelper, 
Expression<Func<TModel, TProperty>> expression,
IEnumerable<TListItem> enumeratedItems,
string idPropertyName,
string displayPropertyName,
string titlePropertyName,
object htmlAttributes
)
 where TModel : class
{
//initialize values
var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var propertyName = metaData.PropertyName;
var propertyValue = metaData.Model.ToStringOrEmpty();
var enumeratedType = typeof(TListItem);

//build the select tag
var returnText = string.Format("<select id=\"{0}\" name=\"{0}\"", HttpUtility.HtmlEncode(propertyName));
if (htmlAttributes != null)
{
foreach (var kvp in htmlAttributes.GetType().GetProperties()
.ToDictionary(p => p.Name, p => p.GetValue(htmlAttributes, null)))
{
returnText += string.Format(" {0}=\"{1}\"", HttpUtility.HtmlEncode(kvp.Key),
HttpUtility.HtmlEncode(kvp.Value.ToStringOrEmpty()));
}
}
returnText += ">\n";


//build the options tags
foreach (TListItem listItem in enumeratedItems)
{
var idValue = enumeratedType.GetProperties()
.FirstOrDefault(p => p.Name == idPropertyName)
.GetValue(listItem, null).ToStringOrEmpty();
var titleValue = enumeratedType.GetProperties()
.FirstOrDefault(p => p.Name == titlePropertyName)
.GetValue(listItem, null).ToStringOrEmpty();
var displayValue = enumeratedType.GetProperties()
.FirstOrDefault(p => p.Name == displayPropertyName)
.GetValue(listItem, null).ToStringOrEmpty();
returnText += string.Format("<option value=\"{0}\" title=\"{1}\"",
HttpUtility.HtmlEncode(idValue), HttpUtility.HtmlEncode(titleValue));
if (idValue == propertyValue)
{
returnText += " selected=\"selected\"";
}
returnText += string.Format(">{0}</option>\n", displayValue);
}


//close the select tag
returnText += "</select>";
return new HtmlString(returnText);
}


public static string ToStringOrEmpty(this object target)
{
if (target == null) return string.Empty;
return target.ToString();
}
}
}


Works like a champ!

Tuesday, October 11, 2011

Extension Methods to Translate Interface Values

Today I'm going to talk about using two of my favorite concepts in C#:  interfaces and extension methods.

There are times when I'm using the Entities Framework with MVC.  For any writable objects in my MVC project, I really do not want to shoehorn them into an Entities object; EF will bark at you, there's a lot of complications, and the self-tracking stuff will actually get in your way.

However, at some point, my MVC model needs to allow me to get the data from an Entities data model object, and translate it to view model object, and vice-versa.  For example, let's say we have a database table of Employees:

create table Employees
(
EmployeeID int identity not null primary key,
GivenName varchar(35) not null,
FamilyName varchar(35) not null,
DepartmentID int not null
);

In EF, this will be an Employee object with four primitive properties (EmployeeID, GivenName, FamilyName, and DepartmentID) plus a navigation object property pointing to the Departments table called Department (assuming of course that DepartmentID is a foreign key and you are keeping foreign keys around... I like to) of type Department, another EF entity.

If we are making a model for MVC to edit Employee records, you don't want to use the Entity object; you cannot define any validation properties, the "glue" that holds an EF object is not translatable to the a serializable forms object (well, not strictly true, but it's a lot more work), and of course data state cannot be maintained very easily in a web session... you usually don't want it to anyway.

So we need to define a model object.  Let's do so now:

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;


namespace MyMVCProject.Models.Employees
{
public class EditModel
{
public int EmployeeID { get; set; }


[Required]
[MaxLength(35)]
[Display(Name="Given Name")]
public string GivenName { get; set; }


[Required]
[MaxLength(35)]
[Display(Name="Family Name")]
public string FamilyName { get; set; }


[Required]
public int DepartmentID { get; set; }


public IEnumerable<Department> AvailableDepartments { get; set; }
}
}

There's a lot of overlap between the view model and the entity object; after all, they are referencing the same thing, but because they are meant to do different things they have to be separate.

But now, in the controller, every time we want to link the two objects, we need to go through a translation mechanism:

using System.Web.Mvc;
using MyMVCProject.Models.Employees;
using MyMVCProject.DataModel.Entities;
namespace MyMVCProject.Controllers
{
public class EmployeesController : Controller
{
protected EntitiesUnitOfWork UnitOfWork = new EntitiesUnitOfWork();
public ActionResult Edit(int id)
{
var entity = UnitOfWork.GetEmployee(id);
var model = new EditModel();
model.EmployeeID = entity.EmployeeID;
model.GivenName = entity.GivenName;
model.FamilyName = entity.FamilyName;
model.DepartmentID = entity.DepartmentID;
model.AvailableDepartments = UnitOfWork.GetAvailableDepartments();
return View(model);
}

[HttpPost]
public ActionResult Edit(EditModel model)
{
if (ModelState.IsValid)
{
var entity = UnitOfWork.GetEmployee(model.EmployeeID);
entity.GivenName = model.GivenName;
entity.FamilyName = model.FamilyName;
entity.DepartmentID = model.DepartmentID;
UnitOfWork.Save();
return RedirectToAction("Index");
}
else
{
model.AvailableDepartments = UnitOfWork.GetAvailableDepartments();
return View(model);
}
}
}
}

...and that's just for one view model.  There's likely to be a CreateModel, and maybe a DetailModel as well that the translation would have to be coded for.  That's a lot of repeated code.

So how do you get around having to do that all the time?  With interfaces!

In our data model namespace, we can define an IEmployee interface like so:

namespace MyMVCProject.DataModel.Entities
{
public interface IEmployee
{
int EmployeeID { get; set; }
int DepartmentID { get; set; }
string GivenName { get; set; }
string FamilyName { get; set; }
}
}

...then, make a public partial class Employee in the data model namespace that implements the interface:

namespace MyMVCProject.DataModel.Entities
{
public partial class Employee : IEmployee
{
//nothing needed here; the T4 generated code has already implemented the interface; 
//we are simply defining the class as IEmployee.
}
}

Now, what I like to do at this point (and this is simply a personal preference) is, in the same file where the interface is defined, create a partial static class with an extension method for the translation.  Note that the key properties will need to be handled with care; you don't want to change a key property unless it has not been set.  EF will bark at you, and rightfully so.

namespace MyMVCProject.DataModel.Entities
{
public interface IEmployee
{
int EmployeeID { get; set; }
int DepartmentID { get; set; }
string GivenName { get; set; }
string FamilyName { get; set; }
}

public static partial class Translation
{
public static T Translate<T>(this T current, IEmployee source) where T : IEmployee
{
if (current.EmployeeID == 0)
{
current.EmployeeID = source.EmployeeID;
}
current.DepartmentID = source.DepartmentID;
current.FamilyName = source.FamilyName;
current.GivenName = source.GivenName;
return current;
}
}
}

After this, go back to the MVC view model, and add the reference to the IEmployee interface and the data model namespace.  No other work should be necessary if you kept the property names and data types the same.

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using MyMVCProject.DataModel.Entities;
namespace MyMVCProject.Models.Employees
{
public class EditModel : IEmployee
{
public int EmployeeID { get; set; }

[Required]
[MaxLength(35)]
[Display(Name="Given Name")]
public string GivenName { get; set; }

[Required]
[MaxLength(35)]
[Display(Name="Family Name")]
public string FamilyName { get; set; }

[Required]
public int DepartmentID { get; set; }

public IEnumerable<Department> AvailableDepartments { get; set; }
}
}

Now we can use the method extensions in our controller with impunity:

using System.Web.Mvc;
using MyMVCProject.Models.Employees;
using MyMVCProject.DataModel.Entities;
namespace MyMVCProject.Controllers
{
public class EmployeesController : Controller
{
protected EntitiesUnitOfWork UnitOfWork = new EntitiesUnitOfWork();
public ActionResult Edit(int id)
{
var entity = UnitOfWork.GetEmployee(id);
var model = new EditModel()
.Translate(entity);
model.AvailableDepartments = UnitOfWork.GetAvailableDepartments();
return View(model);
}

[HttpPost]
public ActionResult Edit(EditModel model)
{
if (ModelState.IsValid)
{
var entity = UnitOfWork.GetEmployee(model.EmployeeID)
.Translate(model);
UnitOfWork.Save();
return RedirectToAction("Index");
}
else
{
model.AvailableDepartments = UnitOfWork.GetAvailableDepartments();
return View(model);
}
}
}
}

While this does not seem to save a lot of code in this example, keep in mind, this is a very simple example; few models actually contain so few properties, and we have changed the translation between the view model object(s) and the data model object to exactly one place for everything.  When you add additional models (like a CreateModel, where you need different validation logic), instead of doubling your text, it's just one line that will predictably behave exactly as all the other calls to this extension method.