【问题标题】:Securely encrypting / decrypting appsettings.json on server在服务器上安全地加密/解密 appsettings.json
【发布时间】:2018-05-21 03:18:48
【问题描述】:

如何保护用于加密 Web 应用程序 appsettings.json 中敏感数据的加密密钥?

我想保护我的网络应用程序配置中的敏感数据。

在 ASP.NET MVC4 应用程序中,我们是这样做的:

  1. 敏感数据(例如连接字符串中的密码)不会直接添加到web.config(或web.prod.config等),而是写入占位符变量。
  2. 在部署时,我们的部署服务 (Octopus) 将从其安全存储中检索敏感数据并覆盖 web.config 中的变量。
  3. 然后,部署过程将使用 aspnet_regiis.exe 加密 web.config 的敏感部分。

现在我们使用的是 ASP.NET Core,我们遵循的过程有点不同。

  1. appsettings.json 保存敏感数据的占位符变量, 类似于之前 web.config 的工作方式。
  2. 部署过程像以前一样用其安全存储中的敏感数据替换占位符。
  3. 我相信我需要:而不是使用aspnet_regiis

    a) 制作我自己的自定义工具来加密 appsettings.json 文件的部分内容。

    b) 制作一个可以解密(全部/部分)appsettings.json 的自定义配置提供程序

我不明白如何保护用于 (a) 和 (b) 的加密密钥。旧方法利用服务器的机器密钥来加密文件。

我试图缓解的威胁是有人可以访问服务器上的 appsettings.json 并从中读取敏感数据(例如数据库密码等)

我也对减轻这种威胁和/或这种方法的其他问题的替代方法感兴趣。

【问题讨论】:

  • 您是否在 Azure 上运行?这有一种安全的方式来存储应用程序外部的机密。
  • @JimW 不,我不在 Azure 上。
  • 即使您没有在 Azure 上运行,我仍然建议使用 Azure Key Vault 来存储您的机密。对于初学者来说,它非常便宜(约 0.0159 美元 / 10 000 次操作),其次它可以从任何地方访问,甚至在 Azure 之外。您可以拥有内存缓存,因此仅在应用程序开始时(或缓存过期时)对 Key Vault 进行 REST 调用,从而防止任何进一步的延迟。第三,这是微软推荐的方法。
  • @ThePretendProgrammer 您的评论是迄今为止最好的答案,但我认为它需要在答案而不是评论中才能获得赏金。

标签: encryption asp.net-core connection-string


【解决方案1】:

如果您不“信任”服务器 - 您将无法保护存储在此服务器中的“秘密”。

解释:

无论您发明什么“安全”(=不安全)方案 - 应用程序启动时都必须能够将秘密“解密”成某种“可用”形式。

这意味着“解密”所需的所有“密钥”(证书等)都必须存在于此服务器上,并且应用程序可以访问(否则应用程序无法启动)。

这意味着一些访问服务器和应用程序的坏人也可以访问其上的所有“密钥”,并“解密”您的秘密。可能是通过复制文件,可能是通过反编译您的应用程序,可能是转储您的应用程序内存 - 但它可以。

没有绝对的保护。

【讨论】:

  • 是的,我知道你从哪里来,但仍然觉得在 appsettings.json 中加密机密是值得的,因为在接受this SO question 的答案中的所有原因。例如。当攻击者只能部分访问服务器或配置文件时。在这种情况下,在 ASP.NET Core 中存储密钥以使用机器密钥为 aspnet_regiis 提供类似级别的保护的最佳/最实用的方法是什么?
  • 这是不正确的,深度安全非常重要,如果你的服务器被攻破并不一定意味着攻击者也获得了管理员权限执行命令。
  • @Norcino,无需管理员权限。如果应用程序有足够的权限访问某些秘密(它有,否则它将无法工作),那么任何具有相同“低”访问权限的主体都可以访问相同的秘密。这里的主要问题是谁是坏人,因为“普通”访问者无法访问“appsettings.json”。如果 topicstarter 想要保护自己的网络服务器管理员......这是不可能的。
  • @Dmtry 我同意你的观点,但这并不包括由于漏洞利用或错误配置,未经授权的用户获得对网站文件夹的读取权限的可能性,这将允许读取配置文件.使用安全深度原则,您必须假设可能存在违规行为,并且您需要采取行动限制损害和信息泄露。不能假设入侵者成功冒充管理员。
【解决方案2】:

您似乎对执行此操作的“方法”不感兴趣,但对 ASP.NET Core 支持的推荐方法感兴趣。虽然此处的其他答案提到 Azure KeyVault 作为敏感信息的良好存储,但它不是存储它的方式,而是实际存储。 ASP.NET Core 支持overridable configuration 的概念。即在配置系统中可以注册多个配置提供者,并且它们在事务中注册的顺序。每个注册的都会覆盖以前提供商的设置——当然是它拥有的设置。 换句话说,如果您已经注册了标准 JSON 配置提供程序,然后还假设一个数据库配置提供程序,那么两个提供程序都具有的那些设置将获取由后来定义的提供程序定义的值 - 数据库提供程序。 所以在你的情况下,我建议这样做:

  1. 按原样注册所有默认配置提供程序。
  2. 最后注册Azure Key Vault(或类似的基于秘密存储的提供者)配置提供者。
  3. 使用证书身份验证通过 Key Vault 进行身份验证并读取敏感设置。

虽然这不是与当前流程的 1:1 映射,但它符合 ASP.NET Core 原则。

您可以阅读更多关于 ASP.NET 配置的信息:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/index?tabs=basicconfiguration

您可以在此处阅读有关 Azure KeyVault 配置提供程序的信息:https://docs.microsoft.com/en-us/aspnet/core/security/key-vault-configuration?tabs=aspnetcore2x

如果您不能选择基于证书的身份验证,请考虑将用于连接到 Azure Key Vault 服务的 ClientIdClientSecret 存储在环境变量中,并使用适当的配置提供程序(AddEnvironmentVariables() 扩展方法即可) 来访问这些。

此设置将非常安全。祝你好运!

【讨论】:

    【解决方案3】:

    我正在将评论转换为答案:)

    即使您没有在 Azure 上运行,我仍然建议您使用 Azure Key Vault 来存储您的机密。对于初学者来说,它非常便宜(约 0.0159 美元 / 10 000 次操作),其次它可以从任何地方访问,甚至在 Azure 之外。此外,可以对 Azure Key Vault 中的机密进行版本控制,这是一个很好的功能,可以支持每个环境的多个机密版本(仅用于预生产,因为生产应该有自己的密钥保管库)。 Key Vault NuGet 包具有在 .NET Core 中检索和添加机密的操作。 Here 是文档的链接。

    您可以拥有内存缓存,因此仅在应用程序启动时(或缓存过期时)对 Key Vault 进行 REST 调用(或 Key Vault 包方法调用),从而防止任何进一步的延迟。第三,这是微软推荐的方法。

    希望这会有所帮助。

    【讨论】:

    • 这并不能解决无法访问外部资源或安全策略不允许使用云服务的隔离系统的问题。
    【解决方案4】:

    如果有人未经授权访问服务器,那么窃取机密(例如数据库连接字符串)只是问题的一小部分(@Dmitry 的回答)。

    由于您希望更好地控制秘密数据或配置,可以稍微偏离通常基于appsettings.json的方法。

    您可以获取秘密,使用服务器的证书对它们进行非对称加密,将它们存储在一个单独的文件中(这可能是另一个 .json 文件)然后读取文件并在启动时/在每个网络上解密秘密要求。这样一来,秘密几乎和服务器的证书/私钥一样安全。

    另一种选择:对称加密机密并在启动时将密码提供给 Web 应用程序,以便它可以解密机密。当托管 Web 应用程序的进程重新启动时,您必须再次输入密码(您可以使用单独的机器定期输入密码)。

    另见Data Protection in ASP.NET CoreData Protection samples

    有时,长而神秘的密码或简单的对人类友好的密码的混淆就足够了。也就是说,只是防止窃听。比如说,坐在管理员旁边的某个人将无法阅读和记住一串明显随机的字符。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-29
      相关资源
      最近更新 更多