从Windows Store应用程序的文件中读取/写入加密和认证的数据
本文关键字:加密 数据 认证 读取 Store Windows 应用程序 文件 | 更新日期: 2023-09-27 18:08:02
我想在Windows Metro应用程序中加密文件的内容。所讨论的文件存储在设备的本地(LocalState文件夹)中,并包含一个我不希望用户能够(轻松地)修改的长字符串。应用程序很可能使用对称密钥对文件进行加密和解密。
所提供的保护还有待讨论,因为可以破解应用程序以获得密钥。不过,这对我来说是可以接受的,只要用户不能直接修改/伪造文件。我相信经过身份验证的加密是做到这一点的方法,但我对这个主题的了解并不多。
我花了很长时间试图用Windows Metro API加密字符串,使用SymmetricKeyAlgorithmProvider和EncryptedAndAuthenticatedData类。尽管如此,使用示例(来自Microsoft或Internet)似乎很少,并且几乎总是进行简单的加密(未经身份验证)或经过身份验证而不保存数据。例如,这里的示例仅连续地对数据进行加密和解密。事实上,有些例子每次都生成一个随机密钥,我相信我做不到。
我有这样的东西:
private EncryptedAndAuthenticatedData authenticatedEncryption(string strMsg, string strKey)
{
SymmetricKeyAlgorithmProvider objAlgProv = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesGcm);
IBuffer buffMsg = CryptographicBuffer.ConvertStringToBinary(strMsg, BinaryStringEncoding.Utf8);
IBuffer buffKey = CryptographicBuffer.ConvertStringToBinary(strKey, BinaryStringEncoding.Utf8);
IBuffer buffNonce = CryptographicBuffer.CreateFromByteArray(new byte[]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 });
CryptographicKey key = objAlgProv.CreateSymmetricKey(buffKey);
EncryptedAndAuthenticatedData objEncrypted = CryptographicEngine.EncryptAndAuthenticate(key, buffMsg, buffNonce, null);
return objEncrypted;
}
正如你所看到的,我甚至使用了一个常量nonce,这当然不是理想的,但我找不到其他方法。这个方法可能还有我不知道的其他问题。
有了这个加密方法,然后我尝试用DataContractSerializer序列化EncryptedAndAuthenticatedData对象,没有成功(该类的对象不能被序列化),并且我发现没有办法从其AuthenticationTag和EncryptedData属性构建一个EncryptedAndAuthenticatedData对象(假设我可以将这些写入文件)。
这都意味着我还没有找到正确加密和验证字符串的方法,更不用说将结果保存到文件中以便以后能够读取和解密它(我有另一种验证解密方法,它以相同的方式使用密钥和nonce)。
你知道我是否以及如何用Windows Metro提供的类来做到这一点吗?有没有更好的办法?
所以我认为有一个更容易使用的方法:DataProtectionProvider。
dataprotectionprovider是Microsoft提供的一个类,它使用由机器Id、用户Id和包Id组合而成的密钥对称地加密给定的byte array
或Stream
。它使用简单,应该可以很容易地提供很好的保护。
public async Task<IBuffer> SampleProtectAsync(
String strMsg,
String strDescriptor,
BinaryStringEncoding encoding)
{
// Create a DataProtectionProvider object for the specified descriptor.
DataProtectionProvider Provider = new DataProtectionProvider(strDescriptor);
// Encode the plaintext input message to a buffer.
encoding = BinaryStringEncoding.Utf8;
IBuffer buffMsg = CryptographicBuffer.ConvertStringToBinary(strMsg, encoding);
// Encrypt the message.
IBuffer buffProtected = await Provider.ProtectAsync(buffMsg);
// Execution of the SampleProtectAsync function resumes here
// after the awaited task (Provider.ProtectAsync) completes.
return buffProtected;
}
public async Task<String> SampleUnprotectData(
IBuffer buffProtected,
BinaryStringEncoding encoding)
{
// Create a DataProtectionProvider object.
DataProtectionProvider Provider = new DataProtectionProvider();
// Decrypt the protected message specified on input.
IBuffer buffUnprotected = await Provider.UnprotectAsync(buffProtected);
// Execution of the SampleUnprotectData method resumes here
// after the awaited task (Provider.UnprotectAsync) completes
// Convert the unprotected message from an IBuffer object to a string.
String strClearText = CryptographicBuffer.ConvertBinaryToString(encoding, buffUnprotected);
// Return the plaintext string.
return strClearText;
}
在这种情况下,strDescriptor
描述您希望谁能够访问加密的内容。如果是机器上的任何人,则值为"LOCAL=machine"
。如果只是给定的用户,则值为"LOCAL=user"
。
如果你正在使用MVC或MVVM,你可以很容易地将其添加到LocalStorageController
之类的东西中,以便所有本地存储在离开你的应用程序之前自动加密/解密。
希望这有助于和快乐的编码!