c# - UWP - 跨设备数据加密

标签 c# security encryption uwp

我的 UWP 应用将数据以加密形式存储在设备上的本地 SQLite 数据库中。我用 Windows.Security.Cryptography.DataProtection静态数据和数据流加密/解密类(引用:https://docs.microsoft.com/en-us/windows/uwp/security/cryptography)

我提供 OneDrive 数据备份工具的想法是,用户可以将整个数据库从一台设备备份到 OneDrive,并在另一台设备上安装的应用程序中恢复它。这可以帮助用户在多个设备上使用该应用程序,并且在用户获得新设备的情况下也是如此。

我用 "LOCAL=user" DataProtectionProvider 的描述符类(引用:https://docs.microsoft.com/en-us/uwp/api/windows.security.cryptography.dataprotection.dataprotectionprovider)

我希望如果我在两台不同的设备上使用我的 Microsoft 帐户登录并在一台设备上加密数据,然后在另一台设备上恢复数据,那么数据应该会被解密;然而这并没有发生。

我也无法获得任何文档(除了上面列出的引用资料)。我也搜索了 MS 支持,但没有运气。有人可以帮我解决这个问题吗?

我的要求:在一台 (Windows) 设备上加密的数据应该在另一台 (Windows) 设备中解密(当用户在两台设备上使用相同的 Microsoft 帐户登录时)。

[更新]

这是代码示例:

const BinaryStringEncoding encoding = BinaryStringEncoding.Utf8;
        const string strDescriptor = "LOCAL=user";        

public static async Task<string> ProtectTextAsync(string strClearText)

    {
        DataProtectionProvider Provider = new DataProtectionProvider(strDescriptor);

        IBuffer buffMsg = CryptographicBuffer.ConvertStringToBinary(strClearText, encoding);

        IBuffer buffProtected = await Provider.ProtectAsync(buffMsg);

        return CryptographicBuffer.EncodeToBase64String(buffProtected);
    }

    public static async Task<String> UnprotectTextAsync(string strProtected)
    {
        DataProtectionProvider Provider = new DataProtectionProvider();

        IBuffer buffProtected = CryptographicBuffer.DecodeFromBase64String(strProtected);

        IBuffer buffUnprotected = await Provider.UnprotectAsync(buffProtected);

        String strClearText = CryptographicBuffer.ConvertBinaryToString(encoding, buffUnprotected);

        return strClearText;
    }

代码很简单;然而,错误再现的过程很重要,具体如下:

我在 Windows 10 移动版(操作系统版本:10.0.14393.1770)上运行该应用程序,然后在 OneDrive 上备份数据。我的手机显示我在“设置”-->“帐户”-->“您的信息”中使用 Microsoft 帐户(例如 NP3@msft.com)。

现在,当我运行应用程序并从中恢复备份时,我使用 NP3@msft.com 帐户登录到我的 Windows 10 笔记本电脑(操作系统版本:15063.674 版本:1703 与秋季创作者更新 SDK 仅应用)一个驱动器。
现在,当我尝试访问数据时,出现 IBuffer buffUnprotected = await Provider.UnprotectAsync(buffProtected); 中的错误线的UnprotectTextAsync方法。错误是:
System.Exception: 'The specified data could not be decrypted. (Excep_FromHResult 0x8009002C)'

请注意,如果我从同一设备(移动设备或笔记本电脑)恢复 OneDrive 上备份的数据,则此代码可以正常工作。因此,备份/恢复功能正常工作,无需修改数据。

最佳答案

我会尽量保持简短,但有几种方法可以解决这个问题,首先让我们谈谈 UWP storage第一的。
UWP 提供 API 以将用户首选项和设置以及数据存储在三种类型的存储中:

  • Local :这基本上是将数据作为应用程序数据存储在设备本身的本地存储中。你可以在这里存放什么?它适用于可以序列化的各种数据。它不应该太重,否则它会给你一个 Access Violation Exception .我曾经用它来将图像存储为字节流,因此它在存储方面提供了很大的灵活性。
  • PasswordVault :这通常是为了跨多个设备存储用户凭据,以便用户不必sign in到每台设备上的应用程序,如果您拥有相同的 Microsoft 帐户,它会立即让您登录。您无需显式加密其中的数据,因为 API 在跨设备传输和存储数据时会自动为您加密数据。
  • Roaming :现在这就是您最感兴趣的内容。如果您使用相同的 Microsoft 帐户登录,漫游设置是跨设备传输的设置。数据不会被隐式加密,因此您可能必须为其处理安全方面。一般用于转帐Settings用于应用程序和 Preferences对于用户,如果他/她有一些东西(例如应用程序主题、壁纸)。 Windows 10 OS安装时利用此存储传输各种内容 windows 10在另一台机器上,您可以找到完整列表 here .这真是太棒了。

  • 寻找最佳拟合:
    现在我们已经了解了我们的选项,让我们尝试解决您的问题,以及如何选择存储。
    由于您必须在多个设备上传输数据,Local存储是没有问题的。现在我们还有两个选择 PasswordVaultRoamingStorage / RoamingSettings .

    The question is, what do you want to transfer (for which you use one drive), is it just a bunch of preferences? or is it file(s) of varied sizes? or is it user credentials?


  • 如果是用户凭据,PasswordVault是理想的搭配。它不仅会处理 DataTransfer还提供无缝集成signIn如果用户使用相同的 Microsoft 帐户,则跨设备。
  • 如果只是一堆偏好,那么使用 RoamingSettings .他们将使用 Microsoft 自己的 APIs 将数据传输到其他设备。您所要做的就是从 RoamingStorage 中获取它们容器,您就可以开始使用数据了。
  • 但如果是一堆文件,加密存储在one drive并且您想在下面的其他设备上解密是我推荐的解决方案。

  • 从 oneDrive 读取文件,在其他设备上解密:
    如果您的文件存储在 one drive 上,则该方法可能非常简单。 ,
  • 用户第一次登录app时,查看roamSettings是否存在对于您的应用程序的 Microsoft 帐户是否存在,因为不存在它会返回 null .在这种情况下,创建一个 RoamingStorage并继续执行步骤 2。
  • 创建 keys这将是加密所需要的。 (解释在
    下一节详述)
  • 现在您有了 keys ,您执行所有操作以获取需要写入文件的数据。
  • 使用 keys 加密数据为 encryption一旦数据被加密,将其写入文件并上传到oneDrive .
  • 存储 keys (在下面的下一节中解释)到 roaming storage对于该 Microsoft 帐户。
  • 现在,当用户使用另一台设备登录您的应用时,如 point 1 , 检查是否存在 roamingSettings .只有这一次它不会为空,你会得到用户的 roamingSettings将应用程序导入您的其他设备。提取存储的 key从那里开始并将其保存在 variable 中.
  • oneDrive 下载文件并将其内容阅读为 string .
  • 使用 key存储在变量(点6)中以解密文件的数据
  • 现在您有了实际数据,可以继续您的应用程序流程。

  • 快速了解加密
    加密超出了这个问题的范围,所以我只会解释它的一个基本托梁,如果需要任何帮助,请使用评论部分。
    上述解决方案还取决于您在此处使用的加密类型,如果它
  • Symmetric :如果您使用的是对称的(如 AES ),那么您会生成一个 encryption key和一个 InitializationVector (也称为 IV )在用户登录后立即在第一台设备上并将它们存储在 RoamingSettings 中。
  • Asymmetric :如果您使用非对称(如 RSA ),您将生成一组 key publicKeyprivateKey使用 publicKey加密数据,然后将其存储在 one drive然后存储 privateKey进入漫游设置。

  • It's not recommended to share private keys over the network incase of Asymmetric encryption but, this is a little unconventional but you're using Microsoft's established APIs to transfer data (which they claim to be secure) so that'll reduce the risk.


    如果我跳过了什么,请告诉我。
    从评论中编辑:
    说实话,既然你提到了一个key你说的是AES-256 .现在,如果您不想要 developer要访问 key ,这是默认设置,您将使用 Cryptography APIs由 Microsoft 为 AES .因此,在某种程度上,您将调用一个 API,该 API 将为您提供 key ,而您将调用另一个将加密数据的 API。 最重要 API 将在 runtime 处调用所以无论哪种方式,开发人员都无法访问它。
    但是,如果您的查询是开发人员甚至不应该知道哪种加密以及存储在哪里,那么在这种情况下,我建议您使用 Factory Pattern ,你在哪abstract把得到的数据执行出来encrypted您只需传入数据,即类处理所有 key 的创建、数据的加密和 key 的存储以进行漫游,然后返回加密的数据。

    引用文献:
  • Store and retrieve settings and other app data
  • Credential locker (a.k.a PasswordVault)
  • Windows 10 roaming settings reference
  • Advanced Encryption Standard-AES
  • RSA
  • 关于c# - UWP - 跨设备数据加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47119351/

    相关文章:

    c# - 数据返回 null,谁能告诉我我在这里做错了什么?

    amazon-web-services - 我应该如何将 secret (RDS 密码)传递到 CloudFormation/SAM 创建的 Lambda 函数中?

    sql - 通过查找数据模式来阻止欺诈

    c# - 使用彭博新闻的 RSS 源

    c# - 如何在 C# 中使用 iTextsharp 5.2.0 版在 pdf 的所有页面中添加页眉和页脚

    c# - 从已编译的 DLL 中获取所有 XAML 文件

    php - 保护 WordPress 中的插件数据免遭其他插件访问?

    amazon-web-services - 数据如何在内部存储在 AWS DynamoDB 上?加密还是纯文本?

    vba - putObject 通过加密 S3 存储桶上的预签名 url 返回签名不匹配

    来自 iOS Swift 的 PHP AES256 PKCS7 解密