我有一個最小類來加密和解密沒有時間組件的DateTime對象。下面的測試適用於1988年1月1日,但1988年1月2日失敗,即。第一次迭代通過但第二次失敗。DateTime加密和解密,System.Text.Encoding.Unicode.GetBytes和System.Text.Encoding.Unicode.GetString不按預期工作?
看來我的問題絕對是在字節的加密和解密之外。當在DateTime2EncryptedString調試加密第二次迭代(1988 1月2日),具有以下值:
{字節[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
雖然加密在EncryptedString2DateTime與DateTime2EncryptedString的輸出字符串作爲參數具有以下值:
{字節[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
這個問題來自我誤解字符串(反之亦然)的操作?
測試
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);
}
這裏是小工具類
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
}
嘗試使用Convert.ToBase64String方法存儲加密的字節。加密的字節可以包含序列,這在unicode中不存在。 – Atomosk
工作,非常感謝。你可以添加一些答案和更多細節,以便我可以接受它嗎?或者關於字節數組中序列概念的一些鏈接。 – Jerome
您可以嘗試通過調用'DateTime.ToBinary()'來加密您正在加密的原始'DateTime'值的'DateTime.Date'屬性的長表示形式,而不是加密字符串表示形式。然後,您不必擔心字符串編碼問題或使用格式化方法可能產生的任何其他問題,例如基於本地化的表示問題。 –