Encryption 101: Symmetric Algorithms

Earlier this week, we covered one-way encryption using a hash algorithm and a salted hash. If you need to decrypt what you’ve encrypted, these solutions are out the window. The simplest solution for encrypting and decrypting is to use a symmetric algorithm. Data is encrypted using a secret key, and it’s decrypted the same way–using the secret key. (Symmetric!)

It requires a few more steps to accomplish, but overall, it’s still pretty simple. Let’s breakdown the steps:

  1. Select an algorithm
  2. Create a key
  3. Encrypt data
  4. Decrypt data

That doesn’t sound so bad, right!? So let’s do it!

Select an algorithm

The .NET Framework supports a number of different symmetric algorithms, including DES, RC2, Rijndael, and TripleDES. We’ll use TripleDES in this example, so let’s instantiate our crypto provider.

var algorithm = new TripleDESCryptoServiceProvider();

Create a key

Now that we have our crypto provider, creating our secret key is a breeze.

algorithm.GenerateKey();

But wait! That’s not quite it. We also need to generate an initialization vector (IV), which acts as a “randomizer” for the encryption. Don’t worry, though–it’s just as easy as generating the key.

algorithm.GenerateIV();

Encrypt data

We have our key and IV, so we’re ready to encrypt some data! This is a little more complicated, but still not too bad. All we’re doing is creating an ICryptoTransform “encryptor” from our symmetric crypto provider, then using it to write bytes to a CryptoStream. Sounds hard, but it’s really not so bad.

string Encrypt(SymmetricAlgorithm sa, string text)
{
    var encryptor = sa.CreateEncryptor(sa.Key, sa.IV);
    var bytes = Encoding.UTF8.GetBytes(text);
    using (var ms = new MemoryStream())
    {
        using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
        {
            cs.Write(bytes, 0, bytes.Length);
            cs.FlushFinalBlock();
        }
        return Convert.ToBase64String(ms.ToArray());
    }
}

Decrypt data

Now how do we go about decrypting it? Well, not surprisingly–this being a symmetric algorithm and all–it’s nearly identical to encrypting the data. The only difference is that we create a “decryptor” from our crypto provider.

string Decrypt(SymmetricAlgorithm sa, string encrypted)
{
    var decryptor = sa.CreateDecryptor(sa.Key, sa.IV);
    var bytes = Convert.FromBase64String(encrypted);
    using (var ms = new MemoryStream())
    {
        using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write))
        {
            cs.Write(bytes, 0, bytes.Length);
            cs.FlushFinalBlock();
        }
        return Encoding.UTF8.GetString(ms.ToArray());
    }
}

Putting it all together

Overall, symmetric encryption gives us a quick and easy way to do reasonably secure encryption. To properly decrypt data across applications, you’ll need to share the key and IV that you generated. Make sure to keep these values a secret, though, as they allow anybody to decrypt your sensitive data. Here’s the full example from the pieces above:

namespace adamprescott.net.EncryptionSymmetric
{
    using System;
    using System.IO;
    using System.Security.Cryptography;
    using System.Text;

    class Program
    {
        static void Main(string[] args)
        {
            var p = new Program();
            p.Run();
        }

        void Run()
        {
            Console.Write("Input: ");
            var input = Console.ReadLine();

            using (var algorithm = new TripleDESCryptoServiceProvider())
            {
                algorithm.GenerateKey();
                algorithm.GenerateIV();

                var encrypted = Encrypt(algorithm, input);
                Console.WriteLine("Encrypted: {0}", encrypted);

                var decrypted = Decrypt(algorithm, encrypted);
                Console.WriteLine("Decrypted: {0}", decrypted);
            }

            Console.ReadLine();
        }

        string Encrypt(SymmetricAlgorithm sa, string text)
        {
            var encryptor = sa.CreateEncryptor(sa.Key, sa.IV);
            var bytes = Encoding.UTF8.GetBytes(text);
            using (var ms = new MemoryStream())
            {
                using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                {
                    cs.Write(bytes, 0, bytes.Length);
                    cs.FlushFinalBlock();
                }
                return Convert.ToBase64String(ms.ToArray());
            }
        }

        string Decrypt(SymmetricAlgorithm sa, string encrypted)
        {
            var decryptor = sa.CreateDecryptor(sa.Key, sa.IV);
            var bytes = Convert.FromBase64String(encrypted);
            using (var ms = new MemoryStream())
            {
                using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write))
                {
                    cs.Write(bytes, 0, bytes.Length);
                    cs.FlushFinalBlock();
                }
                return Encoding.UTF8.GetString(ms.ToArray());
            }
        }
    }
}
Advertisements

Encryption 101: This Hash Needs Salt

Yesterday, I wrote about how to do simple, one-way encryption using a hash algorithm. This is terrific for encrypting data that doesn’t need to be decrypted, like user passwords. The problem with hash algorithms is that the same values encrypt to the same encrypted values. This is bad because it is possible to see that two encrypted values are the same.

But do not worry. You can turn a hash into a salted hash with one very easy adjustment: add some random bytes to the value. Of course, in order for this to be effective, you’ll also need to store the salt value. When creating the hash for storage, you’ll use salt+value. When creating the hash for comparison, you’ll use salt+value. Get it?

Here’s a short example that uses the RNGCryptoServiceProvider class (RNG = Random Number Generator) to create a salt:

namespace adamprescott.net.EncryptionSaltedHash
{
    using System;
    using System.Security.Cryptography;
    using System.Text;

    class Program
    {
        static void Main(string[] args)
        {
            var p = new Program();
            p.Run();
        }

        private void Run()
        {
            Console.Write("Input: ");
            var input = Console.ReadLine();

            var salt = GetSalt();
            var hashed = HashText(salt + input);
            Console.WriteLine("Salt: {0}", salt);
            Console.WriteLine("Hashed: {0}", HashText(input));

            Console.WriteLine();
            Console.Write("What did you just enter?: ");
            input = Console.ReadLine();
            if (string.Equals(hashed, HashText(salt + input)))
            {
                Console.WriteLine("You are an honest person.");
            }
            else
            {
                Console.WriteLine("You are a liar!");
            }

            Console.ReadLine();
        }

        private string HashText(string text)
        {
            using (var md5 = new MD5CryptoServiceProvider())
            {
                var bytes = Encoding.UTF8.GetBytes(text);
                var hash = md5.ComputeHash(bytes);
                return Convert.ToBase64String(hash);
            }
        }

        private string GetSalt()
        {
            using (var rng = new RNGCryptoServiceProvider())
            {
                var bytes = new byte[8];
                rng.GetBytes(bytes);
                return Convert.ToBase64String(bytes);
            }
        }
    }
}

Encryption 101: Getting Your Hash On

Encryption can be a daunting topic. It’s mostly used only when needed, and it’s typically needed when sensitive data needs to be protected. There are a lot of different ways to encrypt data, and even “encryption made simple” articles can get very complicated. But, like many topics, it’s really not as difficult as it seems.

Part of simplifying the solution lies in identifying your needs. Let’s look at a very easy scenario: encrypting passwords. Obviously, you don’t want to store passwords in plain text. I’ve inherited systems with plain text passwords, and I think it’s flat-out embarrassing. The seemingly obvious solution would be to encrypt a password before saving it and then decrypt it for comparison during the authentication process. That’s over-complicating it, though; what you need is a hash!

Using a hash algorithm is a great way to create one-way encryption. This is ideal for a scenario like passwords. Encrypt the password, and store the encrypted value. When it’s time to authenticate, encrypt the user input and compare. If the encrypted strings match, so do the passwords.

Here’s an easy way to do MD5 encryption in C#:

namespace adamprescott.net.EncryptionHash
{
    using System;
    using System.Security.Cryptography;
    using System.Text;

    class Program
    {
        static void Main(string[] args)
        {
            var p = new Program();
            p.Run();
        }

        private void Run()
        {
            Console.Write("Input: ");
            var input = Console.ReadLine();
            Console.WriteLine("Hashed: {0}", HashText(input));
            Console.ReadLine();
        }

        private string HashText(string text)
        {
            using (var md5 = new MD5CryptoServiceProvider())
            {
                var bytes = Encoding.UTF8.GetBytes(text);
                var hash = md5.ComputeHash(bytes);
                return Convert.ToBase64String(hash);
            }
        }
    }
}

Want to use a different hash algorithm? No problem! Just change the CryptoServiceProvider. Here’s the same example using SHA1:

namespace adamprescott.net.EncryptionHash
{
    using System;
    using System.Security.Cryptography;
    using System.Text;

    class Program
    {
        static void Main(string[] args)
        {
            var p = new Program();
            p.Run();
        }

        private void Run()
        {
            Console.Write("Input: ");
            var input = Console.ReadLine();
            Console.WriteLine("Hashed: {0}", HashText(input));
            Console.ReadLine();
        }

        private string HashText(string text)
        {
            using (var sha1 = new SHA1CryptoServiceProvider())
            {
                var bytes = Encoding.UTF8.GetBytes(text);
                var hash = sha1.ComputeHash(bytes);
                return Convert.ToBase64String(hash);
            }
        }
    }
}

SqlCommand Parameter Caching

Last week, I wrote a short article about the SqlCommandBuilder.DeriveParameters method that can be used to automatically populate the parameters of a stored procedure command. One of the downsides to this approach is that each call to the method will result in a call to the database. Since stored procedure parameters aren’t typically changing very often, this can result in a lot of unnecessary chatter. So what’s the solution? Cache the parameter collection, of course!

Here’s a very simple way to do just that. I have an abstract class that maintains a static dictionary of SqlParameterCollections, indexed by SQL command. When the static DeriveParameters method is called from within derived classes, the dictionary is checked. If a matching parameter collection is found, it will be used to create a new parameter collection using the existing collection as a blueprint. If no collection is found, SqlCommandBuilder.DeriveParameters is used, and the resulting collection is cached.

public abstract class BaseDataProvider
{
    private static readonly Dictionary<string, SqlParameterCollection> _sqlParameterCollections;

    static BaseDataProvider()
    {
        _sqlParameterCollections = new Dictionary<string, SqlParameterCollection>();
    }

    private static void DeriveParameters(SqlCommand cmd)
    {
        if (_sqlParameterCollections.ContainsKey(cmd.CommandText))
        {
            var paramCollection = _sqlParameterCollections[cmd.CommandText];
            cmd.Parameters.AddRange(
                paramCollection.OfType<SqlParameter>()
                    .Select(x => new SqlParameter
                    {
                        ParameterName = x.ParameterName,
                        SqlDbType = x.SqlDbType,
                        Size = x.Size,
                        Direction = x.Direction
                    })
                    .ToArray()
                );
            return;
        }

        SqlCommandBuilder.DeriveParameters(cmd);
        _sqlParameterCollections.Add(cmd.CommandText, cmd.Parameters);
    }
}

Note that caching stored procedure parameters can have a negative side-effect: if the parameters DO change, your cache may need to be refreshed. This could be handled in a number of ways. You could have the cached parameters expire after a certain amount of time, you could have a manual trigger, or you could build logic into your application that automatically refreshes the cache if the appropriate error condition is detected.

Update 10/10/2012:

The SqlParameter class also implements ICloneable. I’ve updated my caching logic to take advantage of this. Note that you must cast the parameter to ICloneable in order to invoke its Clone method.

private static readonly Dictionary<string, SqlParameter[]> ParameterCache;

// retrieve from cache
if (ParameterCache.ContainsKey(cmd.CommandText))
{
	var paramCollection = ParameterCache[cmd.CommandText];
	cmd.Parameters.AddRange(
		paramCollection.OfType<SqlParameter>()
			.Select(x => ((ICloneable)x).Clone() as SqlParameter)
			.ToArray()
		);
	return;
}

// add to cache
var parameters = cmd.Parameters
	.OfType<SqlParameter>()
	.Select(x => ((ICloneable)x).Clone() as SqlParameter)
	.ToArray();
ParameterCache.Add(cmd.CommandText, parameters);

SqlCommandBuilder.DeriveParameters

One of the first things I learned when getting into .NET was how to access a SQL database. Most of the data access I need to do is stored procedure-based, so I did this by using the Enterprise Library Data Access Block. It was magical, and it worked, so I never asked questions.

The main thing that’s kept me from deviating is the DiscoverParameters method. We use so many stored procedures, and many of them have a large number of parameters. Manually creating parameters in code was just not an option. Today I learned about a fantastic new method that has liberated me, though: SqlCommandBuilder.DeriveParameters.

This handy little method gives me the same benefit of automatically populating a stored procedure command’s SqlParametersCollection. Here’s an example:

var cs = ConfigurationManager.ConnectionStrings["NamedDbConnection"];
using (var conn = new SqlConnection(cs.ConnectionString))
{
	conn.Open();
	using (var cmd = new SqlCommand("SpName", conn))
	{
		cmd.CommandType = CommandType.StoredProcedure;
		SqlCommandBuilder.DeriveParameters(cmd);
		
		cmd.Parameters["@SomeParameter"].Value = someValue;

		using (var reader = cmd.ExecuteReader())
		{
			while (reader.Read())
			{
				var col = reader["SomeColumn"] as string;
			}
		}
	}
}

NuGet-ty Goodness

NuGet has been slowly becoming one of my favorite development tools. There are a number of third party projects that I use pretty regularly. Rhino Mocks, jQuery, SpecFlow, and Enterprise Library, to name a few. In the past, I’ve kept a repository of these DLLs. When I start a new project that needs one of them, I copy the DLL into the new project directory and add a reference.

NuGet takes care of all that for me. It’s an online repository of packages, and I can add references to the packages using the NuGet Package Manager. It’s awesome because now I don’t have to remember where I saved the newest DLLs. I just install the package I need and move on. It’s great!

If you’re new to NuGet, you should definitely try it out. It’s easy and convenient, perfect for big projects and one-shot throwaways, alike. Want to learn more? Read the overview. But really, you should just try it out. I heard about it long ago, but I didn’t really get it until I started using it.

Here’s my ultra-quick-start guide:

  1. Install the Visual Studio Extension
  2. Right-click your project’s References > Manage NuGet Packages
  3. Search for and install packages

That’s it! The package will be installed, relevant files will be created in a packages sub-directory in the solution directory, and references and files will be copied into the project. Try it out; I guarantee you’ll love it!

Microsoft Security Essentials

For as long as I can remember, I’ve been using AVG Free Edition for virus protection on my home PCs and as a recommendation for friends and family. Just today I learned about Microsoft Security Essentials. This is apparently old news, though, as the product was initially launched in 2009. At the time, it was regarded to be quite poor, but it has become better with time.

It sounds like this is now a legitimate option for free anti-virus protection for Windows XP, Vista, and 7. The anti-virus capability of Microsoft Security Essentials has also been baked into Windows Defender for Windows 8.  However, while Microsoft’s anti-virus solution has improved to a respectable level over the years, an article at PC World suggests that AVG is still the best option for free protection. I may consider Windows Defender for friends and family as they go to Windows 8 since it will likely be easier for them to setup and maintain, but I’m sticking with AVG for my PCs.

Sources:

The “Art” of Communication

I’m a drawer. (One who draws, not to be confused with one in a dresser.) Three sentences into any explanation, I start looking around for a whiteboard. I don’t know what I want or am going to draw, I just know that I need to do it.

Sure, I like changing databases into monsters, but that’s not the only reason I draw pictures to supplement many of my discussions. This article at Inc does a good job of identifying several advantages of visual explanations. Here’s the summarized list:

  1. Out of sight is literally out of mind
  2. Visuals allow the brain to take shortcuts
  3. Brains like the familiar
  4. Making hard stuff friendly improves communications

The last point is really the most important for me. If I’m describing a complex system to a peer, it takes a lot of words. It’s really easy to lose track of the pieces. Creating a quick doodle does a better job, and it lets the audience revisit the parts they may not understand by continuously examining the picture. It’s also essential as you communicate ideas to folks at different stages of the Dreyfus model–both higher and lower. A customer might not understand what it means to serialize an object to XML and send it via a socket connection, but they’ll understand what a box labeled “data” with an arrow means.

I like the first point that was made, too: out of sight is literally out of mind. If you diagram the entire system before talking about a change, it’s less likely that you’ll forget about a piece of it when considering the implications of the change. On a note unrelated to visuals, this is also important to keep in mind in any meeting that ends with actionable items. Make sure to document who’s responsible to do what. The verbal agreement is “out of sight” and, therefore, at risk to become “out of mind.”

Have you ever sat through a PowerPoint presentation where each slide has 100 words? It’s not good. You spend more time reading words than listening to the speaker. Even worse is when the speaker goes faster than you can read. You get 3/4 of the way through a slide without hearing a word from the speaker only to be cutoff as they move to the next slide. I really like the example of Jobs as a compelling reason to use visuals as shortcuts. If you show me a slide with a solid block of text, I’m far less likely to retain your message than if you were to show me a slide with a single word, phrase, or image. Keep the message in your slides clear and direct, and speak about the rest.

Output Parameters in Argument Contraints with Rhino Mocks

Today, I was writing tests for a method that had an output parameter in its argument list. With Rhino Mocks, this can be very simple and straightforward. In the cookie-cutter example, you can simply pass in the output parameter the same way you’d pass it to the function.

bool outParam;
var mock = MockRepository.GenerateMock<ISomeInterface>();
mock.Expect(x => x.MethodWithAnOutParam(out outParam));

But, what if you want to use argument constraints? It becomes a little less obvious but still very easy.

var mock = MockRepository.GenerateMock<ISomeInterface>();
bool refParam;
mock.Expect(x => x.MethodWithARefParam(
    Arg<string>.Is.Anything, 
    ref Arg<bool>.Ref(Is.Anything(), true).Dummy));

Note that the value in parentheses is the value that will be assigned to the output parameter passed into the function.

You can use the Ref constraint to similarly deal with ref parameters. Notice that the Ref constraint takes two arguments, though: a Rhino AbstractConstraint and the return value.

var mock = MockRepository.GenerateMock<ISomeInterface>();
bool outParam;
mock.Expect(x => x.MethodWithARefParam(
    Arg<string>.Is.Anything, 
    ref Arg<bool>.Ref(Is.Anything(), true).Dummy));

Listen Slowly, Interview Better

 

Inc.com has an article by Jeff Haden from earlier this week titled “Best Interview Technique You Never Use” that I thought offered some good advice. The article suggests that you’ll get more information and insight by simply pausing for a 5-count before moving on to the next question. Just as it is natural for you, the interviewer, to want to ask another question to kill the silence, the candidate is likely to do the same by elaborating on their response.

I know I’m definitely guilty of doing the opposite, firing question after question at a candidate immediately once I think they’ve finished their response. My rapid-fire technique results in very fast interviews that only scratch the surface. I’m relatively new to interviewing at this stage in my career, and I don’t think I’ve become particularly adept at it yet. Perhaps part of the problem is that I haven’t been listening slowly enough.

This is definitely a tip that I’m going to keep in mind as I work to become a more effective interviewer.