我想在Windows Metro应用程序中加密文件的内容。有问题的文件存储在设备中本地(LocalState文件夹),并包含一个我不希望用户能够(轻松)修改的长字符串。应用程序很可能使用对称密钥加密和解密文件。
这提供的保护可供讨论,因为应用程序可以被破解以获得密钥。不过,这对我来说是可以接受的,只要用户不能直接修改/伪造文件。我相信经过身份验证的加密是这样做的方式,但我对这个主题的了解并不是很好。
我花了很长时间尝试使用Windows Metro API加密字符串,使用 SymmetricKeyAlgorithmProvider 和 EncryptedAndAuthenticatedData 类。然而,使用示例(来自Microsoft或互联网)似乎很少,并且几乎总是进行简单加密(未经过身份验证)或经过身份验证而无需保存数据。例如,示例here仅连续加密和解密数据。事实上,有些例子每次都会生成一个随机密钥,我相信我无法做到。
我有类似的东西:
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;
}
正如你所看到的,我甚至使用恒定的随机数,这当然不理想,但我找不到另一种方法。我不知道这种方法可能存在其他问题。
使用这种加密方法后,我尝试使用 DataContractSerializer 序列化 EncryptedAndAuthenticatedData 对象,但没有成功(该类的对象无法序列化),以及我发现无法从 AuthenticationTag 和 EncryptedData 属性构建EncryptedAndAuthenticatedData对象(假设我可以将其写入文件)。
这就意味着我还没有找到正确加密和验证字符串的方法,更不用说将结果保存到文件以便以后能够读取和解密(我有另一种方法用于经过身份验证的解密,它以相同的方式使用key和nonce。)
您是否知道我是否以及如何使用Windows Metro提供的课程?还有更好的方法吗?
答案 0 :(得分:2)
所以我认为您可以使用更简单的方法:DataProtectionProvider。
DataProtectionProvideris是Microsoft提供的一个类,它使用从机器标识,用户标识和软件包标识的组合派生的密钥对给定的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
之类的内容中,以便在您的应用程序离开应用程序之前自动加密/解密所有本地存储。
希望这有助于编码!