J'ai une classe minimale pour crypter et décrypter les objets DateTime sans un composant temporel. Le test ci-dessous fonctionnerait pour le 1er janvier 1988, mais échouerait pour le 1er janvier 1988, c.-à-d. la première itération passe mais la seconde échoue déjà.Chiffrement et déchiffrement de DateTime, System.Text.Encoding.Unicode.GetBytes et System.Text.Encoding.Unicode.GetString ne fonctionnant pas comme prévu?
Il semble que mon problème est définitivement en dehors du cryptage et du décryptage des octets. Lors du débogage de la deuxième itération (1988 2 janvier), crypté dans DateTime2EncryptedString a la valeur suivante:
{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
Bien crypté dans EncryptedString2DateTime avec la chaîne de sortie DateTime2EncryptedString comme paramètre a la valeur suivante:
{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
Le problème viendrait de mon incompréhension des octets à la chaîne (et vice versa) des opérations?
Le 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);
}
Et voici la petite classe utilitaire
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
}
Essayez de stocker des octets cryptés avec la méthode Convert.ToBase64String. Les octets cryptés peuvent contenir des séquences qui n'existent pas dans unicode. – Atomosk
Cela a fonctionné, merci beaucoup. Pourriez-vous ajouter une réponse avec quelques détails supplémentaires pour que je puisse l'accepter? Ou un lien sur le concept de séquence dans les tableaux d'octets. – Jerome
Plutôt que de chiffrer la représentation sous forme de chaîne, vous pouvez essayer de chiffrer la longue représentation de la propriété 'DateTime.Date' de la valeur' DateTime' d'origine que vous cryptez en appelant 'DateTime.ToBinary()'.Ensuite, vous n'aurez plus à vous préoccuper des problèmes d'encodage de chaînes ou de tout autre problème pouvant survenir lors de l'utilisation de méthodes de formatage, telles que les problèmes de représentation basés sur la localisation. –