好的,我有一个将我的玩家对象序列化为XML文件的方法, 我一直在尝试找到一种在将对象写入文件之前加密数据的方法。 这个主题在这里和互联网上有很多帖子,我试图将所有数据结合起来让它在我的应用程序上运行,并最终得出了这个:
public static async Task SaveAsync<T>(Player player)
{
IRandomAccessStream sessionRandomAccess = null;
string strAlgName = SymmetricAlgorithmNames.AesCbc;
UInt32 keyLength = 32;
CryptographicKey key;
SymmetricKeyAlgorithmProvider objAlg = SymmetricKeyAlgorithmProvider.OpenAlgorithm(strAlgName);
IBuffer keyMaterial = CryptographicBuffer.GenerateRandom(keyLength);
key = objAlg.CreateSymmetricKey(keyMaterial);
IBuffer iv = null;
if (strAlgName.Contains("CBC"))
{
iv = CryptographicBuffer.GenerateRandom(objAlg.BlockLength);
}
StorageFile sessionFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("Data.xml", CreationCollisionOption.ReplaceExisting);
sessionRandomAccess = await sessionFile.OpenAsync(FileAccessMode.ReadWrite);
IBuffer buffEncrypt = CryptographicEngine.Encrypt(key, ReadFully(sessionRandomAccess.AsStream()).AsBuffer(), iv);
DataContractSerializer sessionSerializer = new DataContractSerializer(typeof(Player), new Type[] { typeof(T) });
Stream stream = buffEncrypt.AsStream();
sessionSerializer.WriteObject(stream, player);
await stream.FlushAsync();
}
将流转换为字节数组的方法:
public static byte[] ReadFully(Stream input)
{
using (MemoryStream ms = new MemoryStream())
{
input.CopyTo(ms);
return ms.ToArray();
}
}
现在一切都运作良好,直到WriteObject方法被调用,然后我会收到以下异常:
An exception of type 'System.NotSupportedException' occurred in mscorlib.ni.dll but was not handled in user code
Additional information: Unable to expand length of this stream beyond its capacity.
有没有任何想法如何解决这个问题,为什么会发生这种情况?谢谢。
更新: 我认为我可以添加一个对我有效的解密方法,作为包含加密部分的绝佳答案的补充-由Jay Zuo - MSFT提供。
所以这就是:
public static async Task<Player> LoadAsync<T>()
{
try
{
StorageFile sessionFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("Data.xml", CreationCollisionOption.OpenIfExists);
if (sessionFile == null)
{
return null;
}
IBuffer buffEncrypt = await FileIO.ReadBufferAsync(sessionFile);
String strAlgName = SymmetricAlgorithmNames.AesCbcPkcs7;
CryptographicKey key; // Symmetric key
// Open a symmetric algorithm provider for the specified algorithm.
SymmetricKeyAlgorithmProvider objAlg = SymmetricKeyAlgorithmProvider.OpenAlgorithm(strAlgName);
key = objAlg.CreateSymmetricKey(keyMaterial);
IBuffer buffMsg=CryptographicEngine.Decrypt(key, buffEncrypt, iv);
DataContractSerializer sessionSerializer = new DataContractSerializer(typeof(Player));
return (Player)sessionSerializer.ReadObject(buffMsg.AsStream());
}
catch (Exception e)
{
}
return null;
}
请注意,iv IBuffer 和 keyMaterial 被存储并从数据库中加载,如 Jay Zuo - MSFT 建议的。 希望这能对某些人有所帮助 :)