【问题标题】:Decrypt / Encrypt connection string in web.config in ASP.NET在 ASP.NET 中的 web.config 中解密/加密连接字符串
【发布时间】:2011-09-22 04:49:35
【问题描述】:

我在 web.config 中有一个自定义加密的连接字符串。

我想在应用程序启动期间对此进行解密(第一页是基于母版页的登录页面。登录凭据使用加密的连接字符串进行验证)并且它必须 在应用程序关闭之前加密 - 以任何方式 - 正常关闭或应用程序错误。

我尝试使用 Global.asax 来实现,但由于对 web.config 的任何更改都会重新启动应用程序,因此它进入了一个循环,因此放弃了这种方法。

请注意,我不希望使用 ASP.NET 提供的默认配置加密,因为我使用的是自定义加密。

虽然在启动期间很容易解密连接字符串,但在应用程序关闭期间真的有什么方法可以再次加密吗?

非常感谢!

【问题讨论】:

  • 这不就是 SSL 的用途吗?
  • 没有。我不使用https。我忘了说我用的是 Session。
  • 将其存储在其他位置(例如 App_Data 文件夹)。
  • 什么是“应用程序关闭”?如果我关掉电源,你怎么能加密一些东西?
  • 好点:)我从来没有深入过!

标签: asp.net web-config


【解决方案1】:

我将冒这个风险作为答案,因为我真的看不出你所描述的需要:

  1. 如果应用程序启动时连接字符串已在 web.config *_you_don't_need_to_decrypt_it* 中加密,则您只需在每次实例化数据库连接时对其进行解密。相信我,即使每次打开连接都进行解密连接字符串的性能也可以忽略不计。但是假设你是一个性能狂,你只想解密一次并放入 Session (坏主意,但看起来这就是你正在做的事情),没有什么可担心的,我将在下面的第 3 点解释。

  2. 假设你解密一次(Application_Start,你有什么),为什么说需要再次加密before application closes - by whatever way - either normal close or application error.?连接字符串不是通过网络传输的,它是在服务器端用来实例化与数据库的连接的东西,但它不是别人能做到的通过使用应用程序来查看,当然,除非您将其存储在 ViewState 中,但这将非常愚蠢。

  3. 你提到你在 Session 中存储了一些东西,尽管你不是 100% 清楚你是指连接字符串还是其他东西。假设它是连接字符串(同样,我想不出一个正当的理由。如果有的话,我很抱歉。)这不是任何用户都可以看到的,因为 Session 只不过是服务器上的内存字节 /强>。缓存也是如此。

所以,就是这样。

你解密连接字符串,实例化你的连接,做你的事情并关闭连接。连接字符串可以在 web.config 中永远保持加密;原封不动。

更新

由于 OP 正在使用 Membership 提供程序,因此解决方案是实施您自己的 Membership 提供程序。您可以通过以下链接从 Microsoft 下载演示如何执行此操作的示例项目:http://download.microsoft.com/download/a/b/3/ab3c284b-dc9a-473d-b7e3-33bacfcc8e98/ProviderToolkitSamples.msi

查看SQLConnectionHelper.cs 类。

Here's another post 几乎完全符合您的需求。

更新 2

这是使用反射做同样事情的另一种方法。称其为 hack,但它似乎可以完成工作:

Global.asax 中的Application_PreRequestHandler 内调用此方法,其中connectionString 是您已解密的连接字符串:

private void SetProviderConnectionString(string connectionString)
{
// Set private property of Membership, Role and Profile providers. Do not try this at home!!
var connectionStringField = Membership.Provider.GetType().GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);
            if (connectionStringField != null)
                connectionStringField.SetValue(Membership.Provider, connectionString);

            var roleField = Roles.Provider.GetType().GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);
            if (roleField != null)
                roleField.SetValue(Roles.Provider, connectionString);

            var profileField = ProfileManager.Provider.GetType().GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);
            if (profileField != null)
                profileField.SetValue(ProfileManager.Provider, connectionString);
}

Source.

【讨论】:

  • 我忘了提到连接字符串被 Membership 类 (System.Web.Security) 隐式使用。如果我要使用连接字符串,我肯定可以在代码中解密,但这是 FCL 使用的东西,我认为我无法控制它。
  • 请在implicitly used by Membership class 上详细说明并解释FCL 是什么。关于 Membership 课程,您不是说您提供自己的加密吗?如果 Membership 类隐式使用它,则必须在代码中的某处有一个地方,您可以在其中挂钩以在 Membership 类使用它之前解密连接字符串;否则,Membership 类如何知道如何解密它?
  • @Sathya 我想我知道 FCL 是什么:框架类库。对吗?
  • OK.. 这是完整的场景。我使用一个数据库,它既用于核心应用程序,也用于 AspNetSqlMembershipProvider。现在,登录是登录页面,并且使用 Membership.ValidateUser 方法验证凭据。希望您知道,为了使用 AspNetSqlMembershipProvider,我们需要提供一个连接字符串,它应该按照我的要求进行加密。虽然我可以在验证用户之前在 Login.aspx 中解密它,但如果用户关闭浏览器或发生错误,连接字符串会在 web.config 中解密,这是我无法承受的。
  • 伊卡洛斯,感谢您提供的所有解决方案!会尝试最适合我的。
猜你喜欢
  • 2018-09-23
  • 1970-01-01
  • 2010-12-14
  • 1970-01-01
  • 2012-06-18
  • 1970-01-01
  • 2011-08-19
  • 1970-01-01
  • 2011-06-21
相关资源
最近更新 更多