使用 DataContractSerializer 和 DataProtectionProvider 序列化和加密对象
本文关键字:加密 对象 序列化 DataProtectionProvider DataContractSerializer 使用 | 更新日期: 2023-09-27 18:31:41
我正在尝试将对象序列化为内存流,然后加密此流,然后将其写入文件。无法弄清楚出了什么问题,"解密"后内存流为空。
public static async Task SerializeToFileEncrypt<T>(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<T> DeserializeFromFileDecrypt<T>(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);
}
完成
写入后,您需要移动到MemoryStream
的开头。否则,没有什么可读的,因为你已经定位在最后。
这应该有效:
public static async Task SerializeToFileEncrypt<T>(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<T> DeserializeFromFileDecrypt<T>(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);
}
除了上次发布的答案之外,您需要将 raStream 包装在 using 语句中,因为它是一个 IDisposable 对象。 否则,如果某些代码稍后尝试再次打开该文件,它将失败并拒绝访问,因为文件仍由随机访问流打开。
public static async Task SerializeToFileEncrypt<T>(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();
}
}
}