如何保护存储在web.config中的密码?

joh*_* Gu 29 c# asp.net iis asp.net-mvc web-config

我在web.config文件中添加了以下设置,以启动对外部系统的API调用.所以我存储API URL +用户名+密码如下: -

<appSettings>
    <add key="ApiURL" value="https://...../servlets/AssetServlet" />
    <add key="ApiUserName" value="tmsservice" />
    <add key="ApiPassword" value="test2test2" /> 
Run Code Online (Sandbox Code Playgroud)

然后在我的action方法中,我将在构建Web客户端时引用这些值,如下所示: -

public ActionResult Create(RackJoin rj, FormCollection formValues)
        {
           XmlDocument doc = new XmlDocument();
           using (var client = new WebClient())
                {
                    var query = HttpUtility.ParseQueryString(string.Empty);
                    foreach (string key in formValues)
                    {
                        query[key] = this.Request.Form[key];
                    }

                    query["username"] = System.Web.Configuration.WebConfigurationManager.AppSettings["ApiUserName"];
                    query["password"] = System.Web.Configuration.WebConfigurationManager.AppSettings["ApiPassword"];

                    string apiurl = System.Web.Configuration.WebConfigurationManager.AppSettings["ApiURL"];
Run Code Online (Sandbox Code Playgroud)

但在这一点上,我将公开用户名和密码,这些可以被用户捕获,所以我的问题是如何保护API用户名和密码?

Joe*_*zer 24

您可以使用aspnet_regiis加密web.config.这是为了阻止有权访问您服务器的人员阅读敏感信息.

顺便说一句,我会把你的配置设置放在一个类中,然后可以将它注入你的控制器 - 这将使单元测试更容易.

  • 默认情况下它是安全的 - IIS将阻止Web用户查看它.但是,您可能有一个显示web.config部分的网页,或者您可能在某个需要加密敏感信息的地方托管它. (2认同)

JC *_*ard 13

通常,web.config是一个安全文件,IIS不提供它,因此它不会向向Web服务器发出请求的用户公开.Web服务器只提供特定类型的文件,web.config肯定不是其中之一.

通常,您将数据库连接字符串保存在其中,其中包括密码.现在想象一下web.config不安全的场景.您已为应用程序创建了主要的安全威胁.

因此,特别是只要你的项目不是太大,你就不应该担心它.

然而,您可能有更好的方法,但创建一个名为"资源"的项目,并保存所有关键信息,如设置,consts,枚举等.这将是一个光滑和有组织的方法.

如果您通过网络传递用户名/密码(例如,在安全的API调用的情况下),您可能希望使用https来确保正在传输的信息是加密的,但这与安全性无关web.config文件.

  • 我不同意"你不应该担心[密码的安全性]"的说法.我经常担心web.config中的明文用户名和密码.我在部署脚本中添加了一步,使用aspnet_regiis加密生产web.config.仅仅因为IIS不会提供web.config并不意味着有人不会以某种方式破解你的服务器,只是使用System.IO读取文件并显示它.国际海事组织不应该接受这个答案,因为它建议不要关心安全问题. (43认同)
  • 多么可怕的答案 - 难怪有这么多不安全的IIS和ASP.NET应用程序在野外出现.正确答案是根据下面的第二个答案将您的秘密存储在webroot之外并加密. (9认同)
  • web.config安全性与https无关.如果您通过网络发送/接收数据,那么这就是https发挥作用的地方.如果您仅在服务器上使用web.config上的信息,则无需执行任何操作即可.我上面看到的是你实际上是通过网络发送确实需要http的信息,但这与web.config安全性无关.你可以从一个阶级财产中获取这些信息.所以你说的是两个绝对不同的领域. (5认同)
  • 每当我们将源代码审查作为安全风险时,我都会标记存储在纯文本文件中的任何凭据. (5认同)
  • 这个答案还有另一个问题,那就是web.config通常存储在源代码控制系统中,因此会被复制到各个开发环境中。为了避免传递密码,例如,可以使用apsettings包含密码文件。然后,生产密码只能存储在生产计算机上。 (4认同)
  • 正确的是,用户无权访问服务器上发生的信息流程.一旦完成所有过程,服务器为用户提供结果,通常是html内容以及js,images,css等. (2认同)

Art*_*Art 8

我知道这听起来像是过度工程,但如果可以的话,您确实应该使用秘密管理服务,例如 AWS Secrets Manager 或 Azure Key Vault。

通过将密码(即使是以加密形式)存储在 web.config 或 app.config 中,您会给自己带来一些问题:

  • 现在,您的加密密码将提交给您的源代码管理,使任何具有读取权限的人都可以访问它们。要正确摆脱它们,您需要重写历史记录(如果您正在使用git),这是一个很大的痛苦
  • 虽然从技术上讲,您可以将密码放在计算机级配置中,并且位于源代码管理之外,但当密码更改时,您需要更新所有这些文件
  • 现在获得您的加密密码的任何人都可以尝试使用任一aspnet_regiis.exe工具(如果这就是您用来加密它的工具)来解密它,或者如果您推出了自己的安全性,请使用您的源代码进行逆向工程,找出解密算法和密钥它正在使用
  • 每当您需要更改密码时,您都需要更改该文件并重新部署应用程序。

另一方面,当您使用机密管理服务时,源代码中不会存储任何机密或解密密钥或算法。检索秘密就像这样简单:

对于 Azure 密钥保管库:

var keyVaultUrl = "https://<your-key-vault-name>.vault.azure.net/";
var credential =  new DefaultAzureCredential();    
var client = new SecretClient(vaultUri: new Uri(keyVaultUrl), credential);    
KeyVaultSecret secret = client.GetSecret("<your-secret-name>");    
Console.WriteLine($"{secret.Name}: {secret.Value}");
Run Code Online (Sandbox Code Playgroud)

对于 AWS Secrets Manager(跳过一些错误处理代码):

var client = new AmazonSecretsManagerClient(accessKeyId, secretAccessKey, 
                                            RegionEndpoint.APSoutheast2);
var request = new GetSecretValueRequest {
    SecretId = secretName
};
GetSecretValueResponse response = null;
response = client.GetSecretValueAsync(request).Result;
Run Code Online (Sandbox Code Playgroud)

与本地秘密的存储相比,这种方法有很多优点:

  • 您不必在 Prod/Staging/Dev 环境的配置中存储不同的值——只需读取适当命名的机密(例如“[Dev|Prod|Stag]DBPassword”)
  • 只有选定的少数人可以访问非常重要的秘密(例如,我不知道,比如Transfer all $$$ from Deus account to all E-Coin wallets everywhere授权码)
  • 如果有人窃取您的源代码(心怀不满的员工、意外泄露),您的密码不会被泄露
  • 更改密码很简单——您只需使用管理控制台更新密码并重新启动应用程序即可

我在我的博客上写了几篇文章,展示了如何使用 AWS 和 Azure 设置和读取机密,如果您需要分步指导和完整源代码,请随时查看: