Utilisation de DataContractSerializer et DataProtectionProvider pour sérialiser et chiffrer un object

J’essaie de sérialiser un object dans un stream de mémoire, puis de le chiffrer, puis de l’écrire dans un fichier. Impossible de comprendre ce qui ne va pas, le stream de mémoire est vide après le «décryptage».

public static async Task SerializeToFileEncrypt(T o, StorageFile file) { DataContractSerializer dsc = new DataContractSerializer(typeof(T)); MemoryStream memoryStream = new MemoryStream(); dsc.WriteObject(memoryStream, o); DataProtectionProvider provider = new DataProtectionProvider("Local=User"); var raStream = await file.OpenAsync(FileAccessMode.ReadWrite); using(var filestream = raStream.GetOutputStreamAt(0)) { await provider.ProtectStreamAsync(memoryStream.AsInputStream(), filestream); await filestream.FlushAsync(); } } public static async Task DeserializeFromFileDecrypt(StorageFile file) { DataContractSerializer dsc = new DataContractSerializer(typeof(T)); MemoryStream memoryStream = new MemoryStream(); DataProtectionProvider provider = new DataProtectionProvider(); await provider.UnprotectStreamAsync((await file.OpenStreamForReadAsync()).AsInputStream(), memoryStream.AsOutputStream()); return (T) dsc.ReadObject(memoryStream); } 

Vous devez passer au début de MemoryStream une fois que vous avez fini de l’écrire. Sinon, il n’y a rien à lire car vous êtes déjà positionné à la fin.

Cela devrait fonctionner:

 public static async Task SerializeToFileEncrypt(T o, StorageFile file) { DataContractSerializer dsc = new DataContractSerializer(typeof(T)); MemoryStream memoryStream = new MemoryStream(); dsc.WriteObject(memoryStream, o); memoryStream.Seek(0, SeekOrigin.Begin); // move to the beginning of the stream DataProtectionProvider provider = new DataProtectionProvider("Local=User"); var raStream = await file.OpenAsync(FileAccessMode.ReadWrite); using(var filestream = raStream.GetOutputStreamAt(0)) { await provider.ProtectStreamAsync(memoryStream.AsInputStream(), filestream); await filestream.FlushAsync(); } } public static async Task DeserializeFromFileDecrypt(StorageFile file) { DataContractSerializer dsc = new DataContractSerializer(typeof(T)); MemoryStream memoryStream = new MemoryStream(); DataProtectionProvider provider = new DataProtectionProvider(); await provider.UnprotectStreamAsync((await file.OpenStreamForReadAsync()).AsInputStream(), memoryStream.AsOutputStream()); memoryStream.Seek(0, SeekOrigin.Begin); // move to the beginning of the stream return (T) dsc.ReadObject(memoryStream); } 

Un ajout à la dernière réponse publiée, vous devez envelopper raStream dans une instruction using car il s’agit d’un object IDisposable. Sinon, si un code tente ultérieurement d’ouvrir le fichier, il échouera avec un access refusé, car le fichier est toujours ouvert par le stream d’access aléatoire.

 public static async Task SerializeToFileEncrypt(T o, StorageFile file) { DataContractSerializer dsc = new DataContractSerializer(typeof(T)); MemoryStream memoryStream = new MemoryStream(); dsc.WriteObject(memoryStream, o); memoryStream.Seek(0, SeekOrigin.Begin); // move to the beginning of the stream DataProtectionProvider provider = new DataProtectionProvider("Local=User"); using (var raStream = await file.OpenAsync(FileAccessMode.ReadWrite)) { using (var filestream = raStream.GetOutputStreamAt(0)) { await provider.ProtectStreamAsync(memoryStream.AsInputStream(), filestream); await filestream.FlushAsync(); } } }