I have a minimal class to encrypt and decrypt DateTime objects without a time component. The test below would work for 1988 Jan 01, but fail for 1988 Jan 02, ie. the first iteration passes but the second fails already.
It seems my problem is definitely outside of the encryption and decryption of bytes. When debugging the second iteration (1988 Jan 02), encrypted in DateTime2EncryptedString has the following value:
{byte[16]} [0]: 147 [1]: 1 [2]: 22 [3]: 250 [4]: 74 [5]: 227 [6]: 225 [7]: 91 [8]: 157 [9]: 202 [10]: 138 [11]: 246 [12]: 91 [13]: 131 [14]: 42 [15]: 217
While encrypted in EncryptedString2DateTime with DateTime2EncryptedString's output string as parameter has the following value:
{byte[16]} [0]: 147 [1]: 1 [2]: 22 [3]: 250 [4]: 74 [5]: 227 [6]: 225 [7]: 91 [8]: 157 [9]: 202 [10]: 138 [11]: 246 [12]: 91 [13]: 131 [14]: 253 [15]: 255
The problem would come from my misunderstanding of bytes to string (and vice versa) operations ??
The test
public void Test1()
{
for (int year = 1988; year < 2010; year++)
{
for (int month = 1; month < 12; month++)
{
for (int day = 1; day < 28; day++)
{
var dt = new DateTime(year, month, day);
TestDate(dt);
}
}
}
}
private void TestDate(DateTime dt)
{
var encryptedString = DateEncryption.DateTime2EncryptedString(dt);
var output = DateEncryption.EncryptedString2DateTime(encryptedString);
Assert.AreEqual(dt, output);
}
And here is the small utility class
public static class DateEncryption
{
private static readonly byte[] Key = new byte[]
{
32, 29, 124, 21, 92, 18, 28,34, 74, 85, 14, 91, 51, 28, 73, 49, 54, 99, 1, 192, 211, 253, 251, 252,
237, 142, 161, 178, 199, 208, 97, 98
};
private static readonly byte[] Iv = new byte[] { 19, 28, 33, 77, 131, 178, 192, 200, 215, 148, 247, 192, 184, 127, 3, 7};
private static byte[] Decrypt(byte[] cipherData)
{
byte[] decryptedData;
using (MemoryStream ms = new MemoryStream())
{
using (Rijndael alg = Rijndael.Create())
{
alg.Padding = PaddingMode.None;
alg.Key = Key;
alg.IV = Iv;
using (CryptoStream cs = new CryptoStream(ms,
alg.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherData, 0, cipherData.Length);
}
decryptedData = ms.ToArray();
}
}
return decryptedData;
}
private static byte[] Encrypt(byte[] clearData)
{
byte[] encryptedData;
using (MemoryStream ms = new MemoryStream())
{
using (Rijndael alg = Rijndael.Create())
{
alg.Padding = PaddingMode.None;
alg.Key = Key;
alg.IV = Iv;
using (CryptoStream cs = new CryptoStream(ms,
alg.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearData, 0, clearData.Length);
}
encryptedData = ms.ToArray();
}
}
return encryptedData;
}
#region DateTimeEncryption
public static string DateTime2EncryptedString(DateTime dt)
{
var dt2str = string.Format("{0:D4}{1:D2}{2:D2}", dt.Year, dt.Month, dt.Day);
var str2bytes = System.Text.Encoding.Unicode.GetBytes(dt2str);
var encrypted = Encrypt(str2bytes);
return System.Text.Encoding.Unicode.GetString(encrypted);
}
public static DateTime EncryptedString2DateTime(string s)
{
var encrypted = System.Text.Encoding.Unicode.GetBytes(s);
var decrypted = Decrypt(encrypted);
var bytes2str = System.Text.Encoding.Unicode.GetString(decrypted);
return new DateTime(int.Parse(bytes2str.Substring(0, 4)),
int.Parse(bytes2str.Substring(4, 2)),
int.Parse(bytes2str.Substring(6, 2)));
}
#endregion
}