在ASP.NET中的web.config中解密/加密连接字符串

时间:2011-09-22 04:49:36

标签: asp.net web-config

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

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

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

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

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

非常感谢!

1 个答案:

答案 0 :(得分:0)

我将冒这个风险作为答案,因为我无法真正看到你所描述的需要:

  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只是服务器上的内存字节 / strong>即可。这同样适用于Cache。

  4. 那就是那个。

    您解密连接字符串,实例化您的连接,执行您的操作并关闭连接。连接字符串可以在web.config中保持加密状态;不变。

    <强>更新

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

    查看SQLConnectionHelper.cs课程。

    Here's another post完全按照你的需要做。

    更新2

    这是使用Reflection做同样事情的另一种方法。称之为黑客,但它似乎做了这个工作:

    Application_PreRequestHandler内的Global.asax内部调用此方法,其中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.