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

在ASP.NET的web.config中解密/加密连接字符串,asp.net,web-config,Asp.net,Web Config,我在web.config中有一个自定义加密的连接字符串 我想在应用程序启动时解密这个,第一个页面是基于母版页的登录页面。登录凭据使用加密的连接字符串进行验证,并且必须在应用程序关闭之前对其进行加密—无论以何种方式—正常关闭或应用程序错误 我尝试使用Global.asax实现,但由于对web.config的任何更改都会重新启动应用程序,所以它进入了一个循环,因此放弃了此方法 请注意,我不希望使用ASP.NET提供的默认配置加密,因为我使用的是自定义配置加密 虽然在启动期间解密连接字符串很容易,但在

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

我想在应用程序启动时解密这个,第一个页面是基于母版页的登录页面。登录凭据使用加密的连接字符串进行验证,并且必须在应用程序关闭之前对其进行加密—无论以何种方式—正常关闭或应用程序错误

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

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

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


非常感谢

我将冒这个风险作为答案,因为我看不出你所描述的有什么必要:

如果连接字符串已经在web.config*中加密,那么当应用程序启动时,您不需要解密,只要在每次实例化数据库连接时解密即可。相信我,解密连接字符串的性能可以忽略不计,即使每次打开连接时都这样做。但假设你是一个性能怪胎,你只想解密它一次,然后在会话中加入一个坏主意,但这似乎就是你正在做的,没有什么好担心的,我将在下面的第3点中解释

假设您在应用程序启动后对其进行解密,您拥有什么,为什么说您需要在应用程序关闭之前再次对其进行加密—无论以何种方式—正常关闭或应用程序错误。?连接字符串不是通过线路传输的,它是服务器端用来实例化到数据库的连接的东西,但它不是使用应用程序可以看到的东西,当然,除非您将其存储在ViewState中,但这将是非常愚蠢的

您提到,您在会话中存储了一些内容,但并不完全清楚您是指连接字符串还是其他内容。假设它又是连接字符串,我想不出一个有效的原因。如果有,我道歉。这不是任何用户都能看到的,因为会话只是服务器上的内存字节。缓存也是如此

就这样

解密连接字符串,实例化连接,执行操作并关闭连接。连接字符串可以在web.config中永远保持加密;原封不动

更新

由于OP正在使用成员资格提供程序,因此解决方案是实现您自己的成员资格提供程序。您可以通过以下链接从Microsoft下载演示如何执行此操作的示例项目:

查看SQLConnectionHelper.cs类

做你需要的事情

更新2

这里有另一种使用反射做同样事情的方法。称之为黑客,但它似乎起到了作用:

在Global.asax中的应用程序_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);
}

这不是SSL的用途吗?不,我不使用https。我忘了提到我使用了会话。例如,将它存储在其他应用程序数据文件夹中。什么是应用程序关闭?如果我关掉电源,你怎么能加密东西呢?很好的一点:我从来没有到过这么深的地方!我忘了提到连接字符串是由成员类System.Web.Security隐式使用的。如果我使用连接字符串,我当然可以在代码中解密,但这是FCL使用的东西,我想我无法控制它。请详细说明成员类隐式使用的内容,并解释FCL是什么。关于会员类,你不是说你自己提供加密吗?如果成员类隐式地使用它,那么在代码中的某个地方,必须有一个地方,在成员类使用它之前,您可以钩住它解密连接字符串;否则,成员类将如何知道如何解密它?@Sathya我想我知道FCL是什么:框架类库。对吗?好的。。下面是完整的场景。我使用一个DB,它既用于核心应用程序,也用于AspNetSqlMembershipProvider。现在,登录是登录页面,并且使用Membership.ValidateUser方法验证凭据。希望您知道,要使用AspNetSqlMembershipProvider,我们需要提供一个连接字符串,该字符串应根据我的要求进行加密。虽然我可以在验证用户之前在Login.aspx中对其进行解密,但如果用户关闭浏览器或发生错误,连接字符串将保留在web.config中进行解密,这是我无法负担的。Icarus,感谢您提供的所有解决方案!我会试试哪个最适合我。