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());
            }
        }
    }
}

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;
			}
		}
	}
}

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));

The AssemblyName Class

The other day, I was reading about the Assembly.FullName property, and I noticed this blurb:

Writing your own code to parse display names is not recommended. Instead, pass the display name to the AssemblyName constructor, which parses it and populates the appropriate fields of the new AssemblyName.

AssemblyName? I never knew about that! I checked it out, and it’s what you might expect: an assembly name parser. Here’s the example from MSDN:

using System;
using System.Reflection;

public class AssemblyNameDemo
{
   public static void Main()
   {
      // Create an AssemblyName, specifying the display name, and then 
      // print the properties.
      AssemblyName myAssemblyName = 
         new AssemblyName("Example, Version=1.0.0.2001, Culture=en-US, PublicKeyToken=null");
      Console.WriteLine("Name: {0}", myAssemblyName.Name);
      Console.WriteLine("Version: {0}", myAssemblyName.Version);
      Console.WriteLine("CultureInfo: {0}", myAssemblyName.CultureInfo);
      Console.WriteLine("FullName: {0}", myAssemblyName.FullName);
   }
}
/* This code example produces output similar to the following:

Name: Example
Version: 1.0.0.2001
CultureInfo: en-US
FullName: Example, Version=1.0.0.2001, Culture=en-US, PublicKeyToken=null
 */

Design-Time Data Binding in WPF

One of the cool things that WPF allows you to do is create sample data that can be bound to controls at design-time. This spiffy little feature allows you to do all kinds of tinkering with your UI without having to run your application. A short feedback loop is essential since WPF provides so much flexibility with what you can do. If you have an application that loads a significant amount of data, and you need to load all that data each time you want to see a UI change, that can lead to a significant amount of wasted time.

When you search for how to do this on the web, the most common method is to create a XAML file with your sample data, and then reference the file in the design data context. Here’s a very short example.

Spartan.cs

namespace adamprescott.net.DesignTimeDataBinding
{
    public class Spartan
    {
        public string Profession { get; set; }
        public byte[] Picture { get; set; }
    }
}

SpartanSampleData.xaml (Be sure to change BuildAction to DesignData!)

<m:Spartan xmlns:m="clr-namespace:adamprescott.net.DesignTimeDataBinding" 
           Profession="HooHooHoo">
</m:Spartan>

MainWindow.xaml

<Window x:Class="adamprescott.net.DesignTimeDataBinding.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DataContext="{d:DesignData Source=/SpartanSampleData.xaml}"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DockPanel VerticalAlignment="Top">
            <Image Source="{Binding Picture}" Height="50" />
            <TextBlock Text="{Binding Profession}" />
        </DockPanel>
    </Grid>
</Window>

I had a problem with this method, though. My model had a byte array property that stored image data, and I couldn’t come up with a good way to include a sample image in the design data XAML. I learned that you can also accomplish design-time data binding through the use of static classes, and that gave me exactly what I was looking for: the ability to create and define sample data in code! Here’s the same example as above, modified to use a static class.

SpartanSampleDataContext.cs (Note that I also added an image to the project in the root namespace.)

namespace adamprescott.net.DesignTimeDataBinding
{
    using System;
    using System.IO;
    using System.Reflection;
    using System.Windows;

    public static class SpartanSampleDataContext
    {
        public static Spartan SpartanSampleData
        {
            get
            {
                var result = new Spartan
                {
                    Profession = "HooHooHoo",
                    Picture = GetSampleImageBytes()
                };
                return result;
            }
        }

        private static byte[] GetSampleImageBytes()
        {
            var assemblyName = new AssemblyName(
                Assembly.GetExecutingAssembly().FullName);
            var resourceUri = new Uri(
                String.Format("pack://application:,,,/{0};component/leonidas.jpg", 
                assemblyName.Name));
            using (var stream = Application.GetResourceStream(resourceUri).Stream)
            {
                using (var memoryStream = new MemoryStream())
                {
                    stream.CopyTo(memoryStream);
                    return memoryStream.ToArray();
                }
            }
        }
    }
}

MainWindow.xaml

<Window x:Class="adamprescott.net.DesignTimeDataBinding.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        xmlns:local="clr-namespace:adamprescott.net.DesignTimeDataBinding"
        d:DataContext="{x:Static local:SpartanSampleDataContext.SpartanSampleData}"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DockPanel VerticalAlignment="Top">
            <Image Source="{Binding Picture}" Height="50" />
            <TextBlock Text="{Binding Profession}" />
        </DockPanel>
    </Grid>
</Window>

Closeable Tabs in WPF Made Easy

There are a number of good articles out there about creating closeable tabs in WPF, but they’re very complicated. It shouldn’t be that hard! So, I’m going to try to break it down and make it easy for you.

Here’s what we’re going to do:

  1. Create a new user control for the tab close button
  2. Create a new class that inherits from TabItem
  3. Try it out!

Create a new user control for the tab close button

Add a new UserControl to your project. Since it’s a full-blown UserControl, you can easily style the button however you’d like and add whatever additional code-behind logic you need. The important thing about the control is that it raises a “Close” event that can be handled in our custom TabItem control. You can get fancy with your button, but I wanted to keep it simple for this example so I just used a red button with a white X drawn on it.

XAML:

<UserControl x:Class="adamprescott.net.TabbedDocuments.TabCloseButton"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">

    <Button Click="OnClick" Background="Red">
        <Path Data="M1,9 L9,1 M1,1 L9,9" Stroke="White" StrokeThickness="2" />
    </Button>
    
</UserControl>

Code-behind:

namespace adamprescott.net.TabbedDocuments
{
    using System;
    using System.Windows;
    using System.Windows.Controls;

    public partial class TabCloseButton : UserControl
    {
        public event EventHandler Click;

        public TabCloseButton()
        {
            InitializeComponent();
        }

        private void OnClick(object sender, RoutedEventArgs e)
        {
            if (Click != null)
            {
                Click(sender, e);
            }
        }
    }
}

Create a new class that inherits from TabItem

Add a new class to your project that derives from TabItem. My class has a single method, SetHeader. This method accepts the desired header content as an argument and adds it to a collection with our custom close button.

namespace adamprescott.net.TabbedDocuments
{
    using System.Windows;
    using System.Windows.Controls;

    public class CloseableTabItem : TabItem
    {
        public void SetHeader(UIElement header)
        {
            // Container for header controls
            var dockPanel = new DockPanel();
            dockPanel.Children.Add(header);

            // Close button to remove the tab
            var closeButton = new TabCloseButton();
            closeButton.Click +=
                (sender, e) =>
                {
                    var tabControl = Parent as ItemsControl;
                    tabControl.Items.Remove(this);
                };
            dockPanel.Children.Add(closeButton);

            // Set the header
            Header = dockPanel;
        }
    }
}

Try it out!

Now that all the hard stuff is done, let’s make a sample application to test it out. I have a simple Window with a Button and a TabControl. When the button is clicked, a tab is added with a TextBlock header and a TextBlock content. Each tab can be closed by clicking its close button.

XAML:

<Window x:Class="adamprescott.net.TabbedDocuments.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    
    <DockPanel>
        <Button DockPanel.Dock="Top" Click="OnPlusTabClick">+Tab</Button>
        <TabControl Name="uxTabs">
        </TabControl>
    </DockPanel>
    
</Window>

Code-behind:

namespace adamprescott.net.TabbedDocuments
{
    using System.Windows;
    using System.Windows.Controls;

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void OnPlusTabClick(object sender, RoutedEventArgs e)
        {
            // Create the header
            var header = new TextBlock { Text = "Tab!" };
            
            // Create the content
            var content = new TextBlock
            {
                Text = string.Format("Tab numero {0}-o", 
                    uxTabs.Items.Count + 1)
            };

            // Create the tab
            var tab = new CloseableTabItem();
            tab.SetHeader(header);
            tab.Content = content;

            // Add to TabControl
            uxTabs.Items.Add(tab);
        }
    }
}

See? It didn’t have to be that hard!

Create a Button That Doesn’t Look Like a Button With WPF

One of my favorite things about WPF is that you can make controls look like anything you want. You want a button with text? <Button><TextBlock /></Button> You want a button with an image? <Button><Image /></Button>

So, when I was adding closeable tab functionality to my application, I figured it would be a breeze. When I added the button to the tab header, though, something undesirable happened: it looked like a button. I wanted a close button that just looked like an “X,” not the usual 3D Windows button. Luckily, this is easily accomplished through the use of control templates.

Creating a custom button is a two-step process:

  1. Create a ControlTemplate
  2. Apply the template

Here’s a short example of what I did to create a simple “X” close button:

<Window.Resources>
    <ControlTemplate x:Key="buttonTemplate" TargetType="Button">
        <Path Data="M0,0 L8,8 M8,0 L0,8" Margin="5,5,0,0" Stroke="Black" StrokeThickness="3" />
    </ControlTemplate>
</Window.Resources>

<Button Template="{StaticResource ResourceKey=buttonTemplate}" />

This works just fine, but I’ve created a usability problem. When the user sees or interacts with the button, there are no visual indicators that the item is clickable or anything happens when it’s clicked. No problems, though; we can fix these problems with a pair of style triggers.

<Window.Resources>
    <ControlTemplate x:Key="buttonTemplate" TargetType="Button">
        <Path Data="M0,0 L8,8 M8,0 L0,8" Margin="5,5,0,0" StrokeThickness="3">
            <Path.Style>
                <Style TargetType="{x:Type Path}">
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="False">
                            <Setter Property="Stroke" Value="LightGray" />
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Stroke" Value="Red" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Path.Style>
        </Path>
    </ControlTemplate>
</Window.Resources>

<Button Template="{StaticResource ResourceKey=buttonTemplate}" />

Now when you hover over the button, the X turns red. This is the perfect button for my closeable tab.