从Windows Store应用程序的文件中读取/写入加密和认证的数据

本文关键字:加密 数据 认证 读取 Store Windows 应用程序 文件 | 更新日期: 2023-09-27 18:08:02

我想在Windows Metro应用程序中加密文件的内容。所讨论的文件存储在设备的本地(LocalState文件夹)中,并包含一个我不希望用户能够(轻松地)修改的长字符串。应用程序很可能使用对称密钥对文件进行加密和解密。

所提供的保护还有待讨论,因为可以破解应用程序以获得密钥。不过,这对我来说是可以接受的,只要用户不能直接修改/伪造文件。我相信经过身份验证的加密是做到这一点的方法,但我对这个主题的了解并不多。

我花了很长时间试图用Windows Metro API加密字符串,使用SymmetricKeyAlgorithmProviderEncryptedAndAuthenticatedData类。尽管如此,使用示例(来自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对象,没有成功(该类的对象不能被序列化),并且我发现没有办法从其AuthenticationTagEncryptedData属性构建一个EncryptedAndAuthenticatedData对象(假设我可以将这些写入文件)。

这都意味着我还没有找到正确加密和验证字符串的方法,更不用说将结果保存到文件中以便以后能够读取和解密它(我有另一种验证解密方法,它以相同的方式使用密钥和nonce)。

你知道我是否以及如何用Windows Metro提供的类来做到这一点吗?有没有更好的办法?

从Windows Store应用程序的文件中读取/写入加密和认证的数据

所以我认为有一个更容易使用的方法:DataProtectionProvider。

dataprotectionprovider是Microsoft提供的一个类,它使用由机器Id、用户Id和包Id组合而成的密钥对称地加密给定的byte arrayStream。它使用简单,应该可以很容易地提供很好的保护。

示例文档提供了一个简单的示例:
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之类的东西中,以便所有本地存储在离开你的应用程序之前自动加密/解密。

希望这有助于和快乐的编码!