C# 如何允许导入/导出DPAPI安全凭据

C# 如何允许导入/导出DPAPI安全凭据,c#,encryption,import,export,dpapi,C#,Encryption,Import,Export,Dpapi,我正在编写一个winforms应用程序,它在配置文件中本地存储用户名和密码,这样使用该应用程序的人就不必在每次登录到我的应用程序支持的各种服务时都重新键入凭据。密码能够被解密是绝对必要的,因此我选择使用ProtectedData以及Protect和Unprotect方法来安全地存储密码。这使得将保护其数据的责任轻松地传递给Windows和最终用户,而不用担心密钥之类的问题 现在,我想让用户能够在安装之间移动设置。一个很好的例子是,如果他们想保留大量不同帐户设置的备份,或者他们想移动到不同的计算机

我正在编写一个winforms应用程序,它在配置文件中本地存储用户名和密码,这样使用该应用程序的人就不必在每次登录到我的应用程序支持的各种服务时都重新键入凭据。密码能够被解密是绝对必要的,因此我选择使用ProtectedData以及Protect和Unprotect方法来安全地存储密码。这使得将保护其数据的责任轻松地传递给Windows和最终用户,而不用担心密钥之类的问题

现在,我想让用户能够在安装之间移动设置。一个很好的例子是,如果他们想保留大量不同帐户设置的备份,或者他们想移动到不同的计算机

我发现它是这样的:

  • 用户单击“导出帐户”按钮
  • 应用程序使用“取消保护”解密存储的设置
  • 应用程序将设置写入明文“备份”,然后导入并在新帐户上重新加密
  • 所有这些听起来都很好,直到第三步。第3步让我很烦恼,因为它将密码放在明文中。在这种情况下,是否有导入/导出凭据的最佳做法,或者认为用户有责任保护导出的文件是“可以”的?对我来说,假设用户正确地保护了他们的Windows帐户,这似乎是可以假设的。我甚至不允许他们导入/导出设置文件,但这似乎是一个很大的不便。类似地,我也可能正在构建一个极其罕见的edge案例,即某人拥有如此多的存储帐户,以至于只需不到十年的时间就可以手动重新输入

    如果有经验的人能就这方面提供最佳实践/建议,我将不胜感激。我还不太熟悉如何处理存储凭证的所有复杂问题

    如果有足够的时间和空间,您的本地密钥存储可能会受到影响,我们所做的只是让这变得更加困难

    当我在一个域中的多台计算机上使用DPAPI进行类似的数据保护时,唯一剩下的方法就是您现在的位置。将敏感数据取消保护为纯文本。将它们复制到另一台计算机,然后使用DPAPI保护数据。这看起来不太好,所以我放弃了一起导出数据的选项!并提供了另一种加密方案,允许以安全的方式导出敏感数据

    这可能不是您问题的答案,但当涉及到导出加密数据时,使用DPAPI让您别无选择,只能选择您所拥有的,这是出于设计。

    推荐的做法是使用对称算法(如Rijndael)加密数据。使用非对称算法加密对称算法的密钥。然后,以LCL方式保存非对称算法的公钥/私钥对和加密的对称算法密钥。将它们导出到另一台计算机。使用非对称算法的私钥解密加密的对称算法密钥。然后使用对称密钥解密导出的数据

    要从透视角度看待问题,请在导出时执行以下操作:

  • 用于加密原始数据
  • 通过使用密码对RijndaelManaged使用的密钥进行加密来保护该密钥
  • 在持久化RSA公钥/私钥对时,请确保使用
  • 使用
  • 将第2步加密的密钥(第4步创建的RSA密钥对)和原始加密数据复制到另一台计算机
  • 使用从XML字符串导入RSA公钥/私钥对。清除Xml文件容器公钥/私钥对
  • 现在您的私钥(和公钥)已在新计算机中可用,请使用它来解密RijndaelManaged的密钥
  • 获得RijndaelManaged的密钥后,使用它对原始数据进行解密
  • 现在,这应该足以满足您的场景。使用DPAPI进行常规凭据存储是一种折衷方法,当用户需要将凭据导出到另一台计算机时,可以按照上面列出的步骤1到步骤8进行操作

    虽然在本地存储凭据不是一个好的做法,但有时为了用户体验,我们除了增加加密的复杂性之外别无选择

    使用DPAPI时,请确保配置用户级/计算机级保护,这也是一个熵值