Last week I covered the performance of cryptographic hash algorithms like MD5 and SHA-1. This week I’ll continue by testing the performance of the closely-related encryption algorithms. This includes algorithms like AES, DES, RC2, Rijndael, and TripleDES. Which is fastest? Does the key size, block size, padding mode, or cipher mode matter? Read on to see!

Today’s test pits all of the encryption algorithms available in Unity’s .NET 2.0 Subset against each other. As you can see from the Mono Compatibility page, many work work in “micro” or “web player” mode. Most apps will use at least .NET 2.0 Subset though, so that’s where I drew the line. Here are the algorithms and their corresponding C# classes that I tested:

  • AES – AesManaged
  • DES – DesCryptoServiceProvider
  • RC2 – RC2CryptoServiceProvider
  • Rijndael – RijndaelManaged
  • TripleDES – TripleDESCryptoServiceProvider

Each algorithm can be parameterized in various ways. Today’s test checks the performance of all permutations of the following:

  • Key size
  • Block size
  • Padding mode
  • Cipher mode

Each algorithm allows for different values for each of these. I tested all of them that are allowed and working. The only one that was allowed and not working was RijndaelManaged with 192- or 256-bit block sizes, so I skipped those.

This resulted in many permutations. I measured the performance of each permutation at creating the encryptor class, encrypting 100 KB of data, and decrypting 100 KB of data. Here’s the test script:

using System;
using System.Collections.Generic;
using System.Security.Cryptography;
 
using UnityEngine;
using System.IO;
 
public class TestScript : MonoBehaviour
{
	private string report = string.Empty;
	private System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
	private static readonly byte[] DataToEncrypt = new byte[1024*100];
	private const int NumCreateIterations = 10000;
	private const int NumEncryptIterations = 1;
	private const int NumDecryptIterations = 1;
 
	class AlgorithmPerformance
	{
		public int BlockSize;
		public int KeySize;
		public CipherMode Mode;
		public PaddingMode Padding;
		public long Create;
		public long Encrypt;
		public long Decrypt;
	}
 
	long TimeOperation(int numIterations, Action action)
	{
		stopwatch.Reset();
		stopwatch.Start();
		for (var i = 0; i < numIterations; ++i)
		{
			action();
		}
		return stopwatch.ElapsedMilliseconds;
	}
 
	AlgorithmPerformance[] TimeAlgorithm(
		Func<SymmetricAlgorithm> creator,
		int[] blockSizes,
		int[] keySizes,
		CipherMode[] modes,
		PaddingMode[] paddings
	)
	{
		var perfs = new List<AlgorithmPerformance>();
		foreach (var blockSize in blockSizes)
		{
			foreach (var keySize in keySizes)
			{
				foreach (var mode in modes)
				{
					foreach (var padding in paddings)
					{
						SymmetricAlgorithm algorithm = null;
						var perf = new AlgorithmPerformance
						{
							BlockSize = blockSize,
							KeySize = keySize,
							Mode = mode,
							Padding = padding
						};
						perf.Create = TimeOperation(
							NumCreateIterations,
							() => {
								algorithm = creator();
								algorithm.BlockSize = blockSize;
								algorithm.KeySize = keySize;
								algorithm.Mode = mode;
								algorithm.Padding = padding;
							}
						);
						byte[] cipherText;
						perf.Encrypt = TimeEncrypt(algorithm, out cipherText);
						perf.Decrypt = TimeDecrypt(algorithm, cipherText);
						perfs.Add(perf);
					}
				}
			}
		}
		return perfs.ToArray();
	}
 
	long TimeEncrypt(SymmetricAlgorithm algorithm, out byte[] cipherText)
	{
		using (var outStream = new MemoryStream())
		{
			var enc = algorithm.CreateEncryptor();
			using (var cryptoStream = new CryptoStream(outStream, enc, CryptoStreamMode.Write))
			{
				var time = TimeOperation(
					NumEncryptIterations,
					() => {
						cryptoStream.Write(DataToEncrypt, 0, DataToEncrypt.Length);
						cryptoStream.Close();
					}
				);
				cryptoStream.Close();
				cipherText = outStream.ToArray();
				return time;
			}
		}
	}
 
	long TimeDecrypt(SymmetricAlgorithm algorithm, byte[] cipherText)
	{
		using (var outStream = new MemoryStream())
		{
			var enc = algorithm.CreateDecryptor();
			using (var cryptoStream = new CryptoStream(outStream, enc, CryptoStreamMode.Write))
			{
				return TimeOperation(
					NumDecryptIterations,
					() => {
						cryptoStream.Write(cipherText, 0, cipherText.Length);
						cryptoStream.Close();
					}
				);
			}
		}
	}
 
	void Start()
	{
		Func<string,AlgorithmPerformance,string> getRow = (label, perf) =>
			label
			+ " BlockSize=" + perf.BlockSize
			+ " KeySize=" + perf.KeySize
			+ " CipherMode=" + perf.Mode
			+ " Padding=" + perf.Padding
			+ "," + perf.Create
			+ "," + perf.Encrypt
			+ "," +perf.Decrypt
			+ "\n";
		Func<string,AlgorithmPerformance[],string> getRows = (label, perfs) => {
			var rows = "";
			foreach (var perf in perfs)
			{
				rows += getRow(label, perf);
			}
			return rows;
		};
		var aes = TimeAlgorithm(
			() => new AesManaged(),
			new[] { 128 },
			new[] { 128, 192, 256 },
			new[] { CipherMode.CBC, CipherMode.ECB },
			new[] { PaddingMode.ANSIX923, PaddingMode.ISO10126, PaddingMode.None, PaddingMode.PKCS7, PaddingMode.Zeros }
		);
		var des = TimeAlgorithm(
			() => new DESCryptoServiceProvider(),
			new[] { 64 },
			new[] { 64 },
			new[] { CipherMode.CBC, CipherMode.CFB, CipherMode.ECB },
			new[] { PaddingMode.ANSIX923, PaddingMode.ISO10126, PaddingMode.None, PaddingMode.PKCS7, PaddingMode.Zeros }
		);
		var rc2 = TimeAlgorithm(
			() => new RC2CryptoServiceProvider(),
			new[] { 64 },
			new[] { 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128 },
			new[] { CipherMode.CBC, CipherMode.CFB, CipherMode.ECB },
			new[] { PaddingMode.ANSIX923, PaddingMode.ISO10126, PaddingMode.None, PaddingMode.PKCS7, PaddingMode.Zeros }
		);
		var rijndael = TimeAlgorithm(
			() => new RijndaelManaged(),
			new[] { 128 },
			new[] { 128, 192, 256 },
			new[] { CipherMode.CBC, CipherMode.CFB, CipherMode.ECB },
			new[] { PaddingMode.ANSIX923, PaddingMode.ISO10126, PaddingMode.None, PaddingMode.PKCS7, PaddingMode.Zeros }
		);
		var tripleDes = TimeAlgorithm(
			() => new TripleDESCryptoServiceProvider(),
			new[] { 64 },
			new[] { 128, 192 },
			new[] { CipherMode.CBC, CipherMode.CFB, CipherMode.ECB },
			new[] { PaddingMode.ANSIX923, PaddingMode.ISO10126, PaddingMode.None, PaddingMode.PKCS7, PaddingMode.Zeros }
		);
		report = "Algorithm,Create Time,100KB Encrypt Time,100KB Decrypt Time\n"
			+ getRows("AesManaged", aes)
			+ getRows("DesCryptoServiceProvider", des)
			+ getRows("RC2CryptoServiceProvider", rc2)
			+ getRows("RijndaelManaged", rijndael)
			+ getRows("TripleDESCryptoServiceProvider", tripleDes)
			;
	}
 
	void OnGUI()
	{
		GUI.TextArea(new Rect(0, 0, Screen.width, Screen.height), report);
	}
}

If you want to try out the test yourself, simply paste the above code into a TestScript.cs file in your Unity project’s Assets directory and attach it to the main camera game object in a new, empty project. Then build in non-development mode for 64-bit processors and run it windowed at 640×480 with fastest graphics. I ran it that way on this machine:

  • 2.3 Ghz Intel Core i7-3615QM
  • Mac OS X 10.10.5
  • Unity 5.2.0f3, Mac OS X Standalone, x86_64, non-development
  • 640×480, Fastest, Windowed

And here are the results I got:

Algorithm Create Time 100KB Encrypt Time 100KB Decrypt Time
AesManaged BlockSize=128 KeySize=128 CipherMode=CBC Padding=ANSIX923 98 5 6
AesManaged BlockSize=128 KeySize=128 CipherMode=CBC Padding=ISO10126 75 2 2
AesManaged BlockSize=128 KeySize=128 CipherMode=CBC Padding=None 85 2 2
AesManaged BlockSize=128 KeySize=128 CipherMode=CBC Padding=PKCS7 76 2 2
AesManaged BlockSize=128 KeySize=128 CipherMode=CBC Padding=Zeros 101 1 2
AesManaged BlockSize=128 KeySize=128 CipherMode=ECB Padding=ANSIX923 76 1 1
AesManaged BlockSize=128 KeySize=128 CipherMode=ECB Padding=ISO10126 68 1 1
AesManaged BlockSize=128 KeySize=128 CipherMode=ECB Padding=None 84 1 1
AesManaged BlockSize=128 KeySize=128 CipherMode=ECB Padding=PKCS7 70 2 1
AesManaged BlockSize=128 KeySize=128 CipherMode=ECB Padding=Zeros 83 1 1
AesManaged BlockSize=128 KeySize=192 CipherMode=CBC Padding=ANSIX923 87 2 2
AesManaged BlockSize=128 KeySize=192 CipherMode=CBC Padding=ISO10126 88 2 2
AesManaged BlockSize=128 KeySize=192 CipherMode=CBC Padding=None 89 2 2
AesManaged BlockSize=128 KeySize=192 CipherMode=CBC Padding=PKCS7 77 2 2
AesManaged BlockSize=128 KeySize=192 CipherMode=CBC Padding=Zeros 96 2 2
AesManaged BlockSize=128 KeySize=192 CipherMode=ECB Padding=ANSIX923 86 1 1
AesManaged BlockSize=128 KeySize=192 CipherMode=ECB Padding=ISO10126 73 1 1
AesManaged BlockSize=128 KeySize=192 CipherMode=ECB Padding=None 78 1 1
AesManaged BlockSize=128 KeySize=192 CipherMode=ECB Padding=PKCS7 79 1 1
AesManaged BlockSize=128 KeySize=192 CipherMode=ECB Padding=Zeros 86 1 1
AesManaged BlockSize=128 KeySize=256 CipherMode=CBC Padding=ANSIX923 85 2 2
AesManaged BlockSize=128 KeySize=256 CipherMode=CBC Padding=ISO10126 77 2 2
AesManaged BlockSize=128 KeySize=256 CipherMode=CBC Padding=None 91 2 2
AesManaged BlockSize=128 KeySize=256 CipherMode=CBC Padding=PKCS7 81 2 2
AesManaged BlockSize=128 KeySize=256 CipherMode=CBC Padding=Zeros 101 2 2
AesManaged BlockSize=128 KeySize=256 CipherMode=ECB Padding=ANSIX923 78 2 2
AesManaged BlockSize=128 KeySize=256 CipherMode=ECB Padding=ISO10126 71 2 1
AesManaged BlockSize=128 KeySize=256 CipherMode=ECB Padding=None 87 1 1
AesManaged BlockSize=128 KeySize=256 CipherMode=ECB Padding=PKCS7 74 2 2
AesManaged BlockSize=128 KeySize=256 CipherMode=ECB Padding=Zeros 88 1 1
DesCryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=CBC Padding=ANSIX923 90 10 9
DesCryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=CBC Padding=ISO10126 84 8 8
DesCryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=CBC Padding=None 88 8 11
DesCryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=CBC Padding=PKCS7 81 8 8
DesCryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=CBC Padding=Zeros 94 8 12
DesCryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=CFB Padding=ANSIX923 86 67 71
DesCryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=CFB Padding=ISO10126 79 64 62
DesCryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=CFB Padding=None 84 69 61
DesCryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=CFB Padding=PKCS7 88 70 66
DesCryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=CFB Padding=Zeros 97 69 67
DesCryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=ECB Padding=ANSIX923 82 7 7
DesCryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=ECB Padding=ISO10126 78 7 7
DesCryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=ECB Padding=None 77 7 7
DesCryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=ECB Padding=PKCS7 76 7 7
DesCryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=ECB Padding=Zeros 83 7 7
RC2CryptoServiceProvider BlockSize=64 KeySize=40 CipherMode=CBC Padding=ANSIX923 78 9 4
RC2CryptoServiceProvider BlockSize=64 KeySize=40 CipherMode=CBC Padding=ISO10126 78 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=40 CipherMode=CBC Padding=None 93 6 6
RC2CryptoServiceProvider BlockSize=64 KeySize=40 CipherMode=CBC Padding=PKCS7 86 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=40 CipherMode=CBC Padding=Zeros 100 9 5
RC2CryptoServiceProvider BlockSize=64 KeySize=40 CipherMode=CFB Padding=ANSIX923 91 59 51
RC2CryptoServiceProvider BlockSize=64 KeySize=40 CipherMode=CFB Padding=ISO10126 72 57 51
RC2CryptoServiceProvider BlockSize=64 KeySize=40 CipherMode=CFB Padding=None 79 52 56
RC2CryptoServiceProvider BlockSize=64 KeySize=40 CipherMode=CFB Padding=PKCS7 79 56 50
RC2CryptoServiceProvider BlockSize=64 KeySize=40 CipherMode=CFB Padding=Zeros 99 58 56
RC2CryptoServiceProvider BlockSize=64 KeySize=40 CipherMode=ECB Padding=ANSIX923 80 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=40 CipherMode=ECB Padding=ISO10126 77 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=40 CipherMode=ECB Padding=None 86 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=40 CipherMode=ECB Padding=PKCS7 80 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=40 CipherMode=ECB Padding=Zeros 91 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=48 CipherMode=CBC Padding=ANSIX923 80 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=48 CipherMode=CBC Padding=ISO10126 78 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=48 CipherMode=CBC Padding=None 75 8 5
RC2CryptoServiceProvider BlockSize=64 KeySize=48 CipherMode=CBC Padding=PKCS7 76 9 5
RC2CryptoServiceProvider BlockSize=64 KeySize=48 CipherMode=CBC Padding=Zeros 90 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=48 CipherMode=CFB Padding=ANSIX923 85 55 58
RC2CryptoServiceProvider BlockSize=64 KeySize=48 CipherMode=CFB Padding=ISO10126 67 57 55
RC2CryptoServiceProvider BlockSize=64 KeySize=48 CipherMode=CFB Padding=None 73 55 50
RC2CryptoServiceProvider BlockSize=64 KeySize=48 CipherMode=CFB Padding=PKCS7 79 57 57
RC2CryptoServiceProvider BlockSize=64 KeySize=48 CipherMode=CFB Padding=Zeros 98 62 50
RC2CryptoServiceProvider BlockSize=64 KeySize=48 CipherMode=ECB Padding=ANSIX923 85 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=48 CipherMode=ECB Padding=ISO10126 77 7 3
RC2CryptoServiceProvider BlockSize=64 KeySize=48 CipherMode=ECB Padding=None 80 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=48 CipherMode=ECB Padding=PKCS7 78 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=48 CipherMode=ECB Padding=Zeros 95 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=56 CipherMode=CBC Padding=ANSIX923 86 7 5
RC2CryptoServiceProvider BlockSize=64 KeySize=56 CipherMode=CBC Padding=ISO10126 90 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=56 CipherMode=CBC Padding=None 88 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=56 CipherMode=CBC Padding=PKCS7 82 6 6
RC2CryptoServiceProvider BlockSize=64 KeySize=56 CipherMode=CBC Padding=Zeros 96 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=56 CipherMode=CFB Padding=ANSIX923 85 55 54
RC2CryptoServiceProvider BlockSize=64 KeySize=56 CipherMode=CFB Padding=ISO10126 78 195 74
RC2CryptoServiceProvider BlockSize=64 KeySize=56 CipherMode=CFB Padding=None 70 55 52
RC2CryptoServiceProvider BlockSize=64 KeySize=56 CipherMode=CFB Padding=PKCS7 73 57 50
RC2CryptoServiceProvider BlockSize=64 KeySize=56 CipherMode=CFB Padding=Zeros 92 57 51
RC2CryptoServiceProvider BlockSize=64 KeySize=56 CipherMode=ECB Padding=ANSIX923 75 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=56 CipherMode=ECB Padding=ISO10126 72 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=56 CipherMode=ECB Padding=None 83 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=56 CipherMode=ECB Padding=PKCS7 78 7 3
RC2CryptoServiceProvider BlockSize=64 KeySize=56 CipherMode=ECB Padding=Zeros 76 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=CBC Padding=ANSIX923 78 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=CBC Padding=ISO10126 73 7 4
RC2CryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=CBC Padding=None 76 7 4
RC2CryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=CBC Padding=PKCS7 74 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=CBC Padding=Zeros 92 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=CFB Padding=ANSIX923 88 56 58
RC2CryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=CFB Padding=ISO10126 67 52 54
RC2CryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=CFB Padding=None 67 54 57
RC2CryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=CFB Padding=PKCS7 79 56 55
RC2CryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=CFB Padding=Zeros 92 51 53
RC2CryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=ECB Padding=ANSIX923 83 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=ECB Padding=ISO10126 87 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=ECB Padding=None 81 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=ECB Padding=PKCS7 81 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=64 CipherMode=ECB Padding=Zeros 91 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=72 CipherMode=CBC Padding=ANSIX923 85 7 6
RC2CryptoServiceProvider BlockSize=64 KeySize=72 CipherMode=CBC Padding=ISO10126 74 7 5
RC2CryptoServiceProvider BlockSize=64 KeySize=72 CipherMode=CBC Padding=None 76 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=72 CipherMode=CBC Padding=PKCS7 77 7 4
RC2CryptoServiceProvider BlockSize=64 KeySize=72 CipherMode=CBC Padding=Zeros 93 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=72 CipherMode=CFB Padding=ANSIX923 86 56 53
RC2CryptoServiceProvider BlockSize=64 KeySize=72 CipherMode=CFB Padding=ISO10126 67 52 53
RC2CryptoServiceProvider BlockSize=64 KeySize=72 CipherMode=CFB Padding=None 69 56 56
RC2CryptoServiceProvider BlockSize=64 KeySize=72 CipherMode=CFB Padding=PKCS7 83 52 58
RC2CryptoServiceProvider BlockSize=64 KeySize=72 CipherMode=CFB Padding=Zeros 90 55 62
RC2CryptoServiceProvider BlockSize=64 KeySize=72 CipherMode=ECB Padding=ANSIX923 92 6 5
RC2CryptoServiceProvider BlockSize=64 KeySize=72 CipherMode=ECB Padding=ISO10126 85 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=72 CipherMode=ECB Padding=None 82 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=72 CipherMode=ECB Padding=PKCS7 76 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=72 CipherMode=ECB Padding=Zeros 83 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=80 CipherMode=CBC Padding=ANSIX923 85 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=80 CipherMode=CBC Padding=ISO10126 74 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=80 CipherMode=CBC Padding=None 89 7 4
RC2CryptoServiceProvider BlockSize=64 KeySize=80 CipherMode=CBC Padding=PKCS7 80 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=80 CipherMode=CBC Padding=Zeros 90 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=80 CipherMode=CFB Padding=ANSIX923 94 57 58
RC2CryptoServiceProvider BlockSize=64 KeySize=80 CipherMode=CFB Padding=ISO10126 82 54 50
RC2CryptoServiceProvider BlockSize=64 KeySize=80 CipherMode=CFB Padding=None 92 55 53
RC2CryptoServiceProvider BlockSize=64 KeySize=80 CipherMode=CFB Padding=PKCS7 82 59 52
RC2CryptoServiceProvider BlockSize=64 KeySize=80 CipherMode=CFB Padding=Zeros 95 57 57
RC2CryptoServiceProvider BlockSize=64 KeySize=80 CipherMode=ECB Padding=ANSIX923 90 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=80 CipherMode=ECB Padding=ISO10126 80 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=80 CipherMode=ECB Padding=None 79 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=80 CipherMode=ECB Padding=PKCS7 81 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=80 CipherMode=ECB Padding=Zeros 84 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=88 CipherMode=CBC Padding=ANSIX923 79 7 4
RC2CryptoServiceProvider BlockSize=64 KeySize=88 CipherMode=CBC Padding=ISO10126 69 7 4
RC2CryptoServiceProvider BlockSize=64 KeySize=88 CipherMode=CBC Padding=None 87 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=88 CipherMode=CBC Padding=PKCS7 82 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=88 CipherMode=CBC Padding=Zeros 98 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=88 CipherMode=CFB Padding=ANSIX923 89 61 57
RC2CryptoServiceProvider BlockSize=64 KeySize=88 CipherMode=CFB Padding=ISO10126 86 56 50
RC2CryptoServiceProvider BlockSize=64 KeySize=88 CipherMode=CFB Padding=None 80 60 59
RC2CryptoServiceProvider BlockSize=64 KeySize=88 CipherMode=CFB Padding=PKCS7 79 52 50
RC2CryptoServiceProvider BlockSize=64 KeySize=88 CipherMode=CFB Padding=Zeros 95 56 58
RC2CryptoServiceProvider BlockSize=64 KeySize=88 CipherMode=ECB Padding=ANSIX923 83 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=88 CipherMode=ECB Padding=ISO10126 78 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=88 CipherMode=ECB Padding=None 81 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=88 CipherMode=ECB Padding=PKCS7 79 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=88 CipherMode=ECB Padding=Zeros 92 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=96 CipherMode=CBC Padding=ANSIX923 87 7 5
RC2CryptoServiceProvider BlockSize=64 KeySize=96 CipherMode=CBC Padding=ISO10126 76 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=96 CipherMode=CBC Padding=None 75 7 4
RC2CryptoServiceProvider BlockSize=64 KeySize=96 CipherMode=CBC Padding=PKCS7 82 8 4
RC2CryptoServiceProvider BlockSize=64 KeySize=96 CipherMode=CBC Padding=Zeros 91 6 6
RC2CryptoServiceProvider BlockSize=64 KeySize=96 CipherMode=CFB Padding=ANSIX923 89 56 59
RC2CryptoServiceProvider BlockSize=64 KeySize=96 CipherMode=CFB Padding=ISO10126 82 58 55
RC2CryptoServiceProvider BlockSize=64 KeySize=96 CipherMode=CFB Padding=None 82 59 53
RC2CryptoServiceProvider BlockSize=64 KeySize=96 CipherMode=CFB Padding=PKCS7 80 56 53
RC2CryptoServiceProvider BlockSize=64 KeySize=96 CipherMode=CFB Padding=Zeros 100 56 49
RC2CryptoServiceProvider BlockSize=64 KeySize=96 CipherMode=ECB Padding=ANSIX923 85 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=96 CipherMode=ECB Padding=ISO10126 76 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=96 CipherMode=ECB Padding=None 79 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=96 CipherMode=ECB Padding=PKCS7 74 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=96 CipherMode=ECB Padding=Zeros 82 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=104 CipherMode=CBC Padding=ANSIX923 89 7 4
RC2CryptoServiceProvider BlockSize=64 KeySize=104 CipherMode=CBC Padding=ISO10126 75 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=104 CipherMode=CBC Padding=None 74 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=104 CipherMode=CBC Padding=PKCS7 78 6 6
RC2CryptoServiceProvider BlockSize=64 KeySize=104 CipherMode=CBC Padding=Zeros 96 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=104 CipherMode=CFB Padding=ANSIX923 93 55 55
RC2CryptoServiceProvider BlockSize=64 KeySize=104 CipherMode=CFB Padding=ISO10126 80 54 51
RC2CryptoServiceProvider BlockSize=64 KeySize=104 CipherMode=CFB Padding=None 82 55 54
RC2CryptoServiceProvider BlockSize=64 KeySize=104 CipherMode=CFB Padding=PKCS7 83 57 54
RC2CryptoServiceProvider BlockSize=64 KeySize=104 CipherMode=CFB Padding=Zeros 90 57 50
RC2CryptoServiceProvider BlockSize=64 KeySize=104 CipherMode=ECB Padding=ANSIX923 98 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=104 CipherMode=ECB Padding=ISO10126 79 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=104 CipherMode=ECB Padding=None 87 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=104 CipherMode=ECB Padding=PKCS7 90 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=104 CipherMode=ECB Padding=Zeros 82 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=112 CipherMode=CBC Padding=ANSIX923 82 8 5
RC2CryptoServiceProvider BlockSize=64 KeySize=112 CipherMode=CBC Padding=ISO10126 84 8 4
RC2CryptoServiceProvider BlockSize=64 KeySize=112 CipherMode=CBC Padding=None 77 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=112 CipherMode=CBC Padding=PKCS7 75 7 4
RC2CryptoServiceProvider BlockSize=64 KeySize=112 CipherMode=CBC Padding=Zeros 89 7 5
RC2CryptoServiceProvider BlockSize=64 KeySize=112 CipherMode=CFB Padding=ANSIX923 85 57 52
RC2CryptoServiceProvider BlockSize=64 KeySize=112 CipherMode=CFB Padding=ISO10126 80 52 50
RC2CryptoServiceProvider BlockSize=64 KeySize=112 CipherMode=CFB Padding=None 80 59 58
RC2CryptoServiceProvider BlockSize=64 KeySize=112 CipherMode=CFB Padding=PKCS7 84 52 50
RC2CryptoServiceProvider BlockSize=64 KeySize=112 CipherMode=CFB Padding=Zeros 96 56 54
RC2CryptoServiceProvider BlockSize=64 KeySize=112 CipherMode=ECB Padding=ANSIX923 89 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=112 CipherMode=ECB Padding=ISO10126 83 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=112 CipherMode=ECB Padding=None 81 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=112 CipherMode=ECB Padding=PKCS7 78 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=112 CipherMode=ECB Padding=Zeros 82 8 4
RC2CryptoServiceProvider BlockSize=64 KeySize=120 CipherMode=CBC Padding=ANSIX923 84 7 4
RC2CryptoServiceProvider BlockSize=64 KeySize=120 CipherMode=CBC Padding=ISO10126 83 7 6
RC2CryptoServiceProvider BlockSize=64 KeySize=120 CipherMode=CBC Padding=None 95 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=120 CipherMode=CBC Padding=PKCS7 86 7 4
RC2CryptoServiceProvider BlockSize=64 KeySize=120 CipherMode=CBC Padding=Zeros 83 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=120 CipherMode=CFB Padding=ANSIX923 88 56 50
RC2CryptoServiceProvider BlockSize=64 KeySize=120 CipherMode=CFB Padding=ISO10126 88 58 53
RC2CryptoServiceProvider BlockSize=64 KeySize=120 CipherMode=CFB Padding=None 87 56 53
RC2CryptoServiceProvider BlockSize=64 KeySize=120 CipherMode=CFB Padding=PKCS7 81 58 55
RC2CryptoServiceProvider BlockSize=64 KeySize=120 CipherMode=CFB Padding=Zeros 94 58 54
RC2CryptoServiceProvider BlockSize=64 KeySize=120 CipherMode=ECB Padding=ANSIX923 81 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=120 CipherMode=ECB Padding=ISO10126 80 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=120 CipherMode=ECB Padding=None 75 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=120 CipherMode=ECB Padding=PKCS7 84 7 4
RC2CryptoServiceProvider BlockSize=64 KeySize=120 CipherMode=ECB Padding=Zeros 76 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=CBC Padding=ANSIX923 78 7 4
RC2CryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=CBC Padding=ISO10126 82 7 6
RC2CryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=CBC Padding=None 86 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=CBC Padding=PKCS7 85 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=CBC Padding=Zeros 92 9 5
RC2CryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=CFB Padding=ANSIX923 87 53 54
RC2CryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=CFB Padding=ISO10126 82 60 57
RC2CryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=CFB Padding=None 76 53 56
RC2CryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=CFB Padding=PKCS7 89 52 54
RC2CryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=CFB Padding=Zeros 79 57 55
RC2CryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=ECB Padding=ANSIX923 85 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=ECB Padding=ISO10126 76 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=ECB Padding=None 84 6 4
RC2CryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=ECB Padding=PKCS7 83 6 3
RC2CryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=ECB Padding=Zeros 87 6 3
RijndaelManaged BlockSize=128 KeySize=128 CipherMode=CBC Padding=ANSIX923 90 4 3
RijndaelManaged BlockSize=128 KeySize=128 CipherMode=CBC Padding=ISO10126 69 2 2
RijndaelManaged BlockSize=128 KeySize=128 CipherMode=CBC Padding=None 82 1 2
RijndaelManaged BlockSize=128 KeySize=128 CipherMode=CBC Padding=PKCS7 81 2 2
RijndaelManaged BlockSize=128 KeySize=128 CipherMode=CBC Padding=Zeros 93 1 2
RijndaelManaged BlockSize=128 KeySize=128 CipherMode=CFB Padding=ANSIX923 84 2 1
RijndaelManaged BlockSize=128 KeySize=128 CipherMode=CFB Padding=ISO10126 79 2 2
RijndaelManaged BlockSize=128 KeySize=128 CipherMode=CFB Padding=None 92 2 2
RijndaelManaged BlockSize=128 KeySize=128 CipherMode=CFB Padding=PKCS7 77 2 2
RijndaelManaged BlockSize=128 KeySize=128 CipherMode=CFB Padding=Zeros 98 2 2
RijndaelManaged BlockSize=128 KeySize=128 CipherMode=ECB Padding=ANSIX923 81 1 1
RijndaelManaged BlockSize=128 KeySize=128 CipherMode=ECB Padding=ISO10126 74 1 1
RijndaelManaged BlockSize=128 KeySize=128 CipherMode=ECB Padding=None 79 1 1
RijndaelManaged BlockSize=128 KeySize=128 CipherMode=ECB Padding=PKCS7 76 1 1
RijndaelManaged BlockSize=128 KeySize=128 CipherMode=ECB Padding=Zeros 84 1 1
RijndaelManaged BlockSize=128 KeySize=192 CipherMode=CBC Padding=ANSIX923 90 2 2
RijndaelManaged BlockSize=128 KeySize=192 CipherMode=CBC Padding=ISO10126 77 2 2
RijndaelManaged BlockSize=128 KeySize=192 CipherMode=CBC Padding=None 82 2 2
RijndaelManaged BlockSize=128 KeySize=192 CipherMode=CBC Padding=PKCS7 81 2 2
RijndaelManaged BlockSize=128 KeySize=192 CipherMode=CBC Padding=Zeros 96 2 2
RijndaelManaged BlockSize=128 KeySize=192 CipherMode=CFB Padding=ANSIX923 96 2 2
RijndaelManaged BlockSize=128 KeySize=192 CipherMode=CFB Padding=ISO10126 84 2 2
RijndaelManaged BlockSize=128 KeySize=192 CipherMode=CFB Padding=None 84 2 2
RijndaelManaged BlockSize=128 KeySize=192 CipherMode=CFB Padding=PKCS7 81 2 2
RijndaelManaged BlockSize=128 KeySize=192 CipherMode=CFB Padding=Zeros 99 2 2
RijndaelManaged BlockSize=128 KeySize=192 CipherMode=ECB Padding=ANSIX923 77 1 1
RijndaelManaged BlockSize=128 KeySize=192 CipherMode=ECB Padding=ISO10126 81 1 1
RijndaelManaged BlockSize=128 KeySize=192 CipherMode=ECB Padding=None 76 2 1
RijndaelManaged BlockSize=128 KeySize=192 CipherMode=ECB Padding=PKCS7 76 2 1
RijndaelManaged BlockSize=128 KeySize=192 CipherMode=ECB Padding=Zeros 84 1 1
RijndaelManaged BlockSize=128 KeySize=256 CipherMode=CBC Padding=ANSIX923 79 2 2
RijndaelManaged BlockSize=128 KeySize=256 CipherMode=CBC Padding=ISO10126 81 2 2
RijndaelManaged BlockSize=128 KeySize=256 CipherMode=CBC Padding=None 82 2 2
RijndaelManaged BlockSize=128 KeySize=256 CipherMode=CBC Padding=PKCS7 79 2 2
RijndaelManaged BlockSize=128 KeySize=256 CipherMode=CBC Padding=Zeros 102 2 2
RijndaelManaged BlockSize=128 KeySize=256 CipherMode=CFB Padding=ANSIX923 94 2 2
RijndaelManaged BlockSize=128 KeySize=256 CipherMode=CFB Padding=ISO10126 73 2 2
RijndaelManaged BlockSize=128 KeySize=256 CipherMode=CFB Padding=None 88 2 2
RijndaelManaged BlockSize=128 KeySize=256 CipherMode=CFB Padding=PKCS7 81 3 2
RijndaelManaged BlockSize=128 KeySize=256 CipherMode=CFB Padding=Zeros 93 2 2
RijndaelManaged BlockSize=128 KeySize=256 CipherMode=ECB Padding=ANSIX923 86 2 2
RijndaelManaged BlockSize=128 KeySize=256 CipherMode=ECB Padding=ISO10126 78 2 2
RijndaelManaged BlockSize=128 KeySize=256 CipherMode=ECB Padding=None 75 2 2
RijndaelManaged BlockSize=128 KeySize=256 CipherMode=ECB Padding=PKCS7 74 2 2
RijndaelManaged BlockSize=128 KeySize=256 CipherMode=ECB Padding=Zeros 83 1 1
TripleDESCryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=CBC Padding=ANSIX923 81 18 18
TripleDESCryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=CBC Padding=ISO10126 83 20 19
TripleDESCryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=CBC Padding=None 87 22 22
TripleDESCryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=CBC Padding=PKCS7 85 18 18
TripleDESCryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=CBC Padding=Zeros 88 22 21
TripleDESCryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=CFB Padding=ANSIX923 81 151 145
TripleDESCryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=CFB Padding=ISO10126 86 162 151
TripleDESCryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=CFB Padding=None 87 154 153
TripleDESCryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=CFB Padding=PKCS7 81 149 154
TripleDESCryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=CFB Padding=Zeros 87 166 164
TripleDESCryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=ECB Padding=ANSIX923 86 22 18
TripleDESCryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=ECB Padding=ISO10126 83 17 17
TripleDESCryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=ECB Padding=None 84 21 23
TripleDESCryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=ECB Padding=PKCS7 78 20 18
TripleDESCryptoServiceProvider BlockSize=64 KeySize=128 CipherMode=ECB Padding=Zeros 90 17 18
TripleDESCryptoServiceProvider BlockSize=64 KeySize=192 CipherMode=CBC Padding=ANSIX923 87 18 23
TripleDESCryptoServiceProvider BlockSize=64 KeySize=192 CipherMode=CBC Padding=ISO10126 79 18 22
TripleDESCryptoServiceProvider BlockSize=64 KeySize=192 CipherMode=CBC Padding=None 75 18 22
TripleDESCryptoServiceProvider BlockSize=64 KeySize=192 CipherMode=CBC Padding=PKCS7 79 18 23
TripleDESCryptoServiceProvider BlockSize=64 KeySize=192 CipherMode=CBC Padding=Zeros 86 21 22
TripleDESCryptoServiceProvider BlockSize=64 KeySize=192 CipherMode=CFB Padding=ANSIX923 91 153 153
TripleDESCryptoServiceProvider BlockSize=64 KeySize=192 CipherMode=CFB Padding=ISO10126 78 146 150
TripleDESCryptoServiceProvider BlockSize=64 KeySize=192 CipherMode=CFB Padding=None 95 157 151
TripleDESCryptoServiceProvider BlockSize=64 KeySize=192 CipherMode=CFB Padding=PKCS7 76 157 151
TripleDESCryptoServiceProvider BlockSize=64 KeySize=192 CipherMode=CFB Padding=Zeros 85 162 148
TripleDESCryptoServiceProvider BlockSize=64 KeySize=192 CipherMode=ECB Padding=ANSIX923 75 19 20
TripleDESCryptoServiceProvider BlockSize=64 KeySize=192 CipherMode=ECB Padding=ISO10126 97 22 21
TripleDESCryptoServiceProvider BlockSize=64 KeySize=192 CipherMode=ECB Padding=None 76 23 19
TripleDESCryptoServiceProvider BlockSize=64 KeySize=192 CipherMode=ECB Padding=PKCS7 91 21 18
TripleDESCryptoServiceProvider BlockSize=64 KeySize=192 CipherMode=ECB Padding=Zeros 81 20 18

AES Encrypt Performance

AES Create Performance

DES Create Performance

DES Encrypt Performance

There are so many permutations of RC2 that the graph became too large. I trimmed it to just a representative sample. For full results, see the table above.

RC2 Create Performance

RC2 Encrypt Performance

Rijndael Create Performance

Rijndael Encrypt Performance

TripleDES Create Performance

TripleDES Encrypt Performance

That’s a lot of data! Let’s start with an easy takeaway: creation time is the same across the board at about 80 milliseconds per 1000 creations or 0.08 milliseconds each. That may not seem like much, but it can add up if you’re encrypting a lot of small items and not reusing instances. Even so, most of the time is spent in setting the parameters. One easy optimization is to avoid setting any parameters you don’t need to. Unfortunately, setting the initialization vector takes quite a while also, so even reusing instances will be very expensive if you’re swapping out the initialization vector often.

Now for the actual encryption and decryption performance. In broad strokes we can say that AES and Rijndael are the fastest at about 1-2 milliseconds per 100 KB. That makes sense since they’re actually the same algorithm. Fortunately, they’re also currently the strongest encryption algorithm of the bunch, so you can have performance and security at the same time.

As for the other encryption algorithms, DES and RC2 clock in around 5-10 milliseconds and TripleDES hits about 20 milliseconds using the CBC and ECB modes that AES and Rijndael are limited to. However, DES and RC2 skyrocket to the 50-70 millisecond range when you use the CFB cipher mode and TripleDES does even worse at 140-160 milliseconds. Unless you have a really good reason, it’s best to avoid CFB mode and stick to the plenty-secure CBC.

Block size, key size, and padding mode turn out to be irrelevant. There may be some extremely minor difference to be found, but in the bigger picture it’s almost impossible to see any impact that any of them have. For best security, use the biggest key size you can and enable a strong padding mode like PKCS7.

In conclusion, we have a happy coincidence where the strongest security settings are actually the fastest: AES with a 256-bit key, PKCS7 padding, and CBC cipher mode. Stay away from the others unless you need to specifically conform to a particular encryption standard.

If you’ve used encryption in Unity and learned anything interesting, please post a comment to let me know!