【问题标题】:Read custom encrypted connection string from Web.config从 Web.config 读取自定义加密连接字符串
【发布时间】:2014-03-07 13:36:37
【问题描述】:

我有一个现有的 ASP.NET 项目,其中连接字符串在 Web.config 文件中通过使用 C# 中的自定义加密函数进行加密,并将该加密字符串保存到 Web.config 文件中,如下所示...

<add name="ConnectionString" connectionString="+tj/H0V/Wpa+UBWzHvOfuL4GPyoDssypPKfeRdUU1FnfHw+phOEBLpRne/ytv1v8gs7P0DoSC7rhN2aPWG3uZZvSis5f/Dqu53HgsRH8m44=" providerName="System.Data.SqlClient" />

我现在想向这个项目添加一个页面,其中包含一个需要 SQLDataSource 的控件,并且我在后面的 .aspx 代码中指定了 ConnectionString,作为 SQLDataSource 的属性,如下所示...

<asp:SqlDataSource ID="PeriodsDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:ConnectionString %>"

这显然是现在试图读取connectionString,但是得到了Encrypted String,并抛出了错误......

"关键字不支持: '+tj/h0v/wpa+ubwzhvoful4gpyodssyppkferduu1fnfhw+phoeblprne/ytv1v8gs7p0dosc7rhn2apwg3uzzvsis5f/dqu53hgsrh8m44'。”

如何将 ConnectionString 传递给我的自定义 Encryption.Decrypt 函数,以便 SQLDataSource 使用未加密的字符串?

我尝试简单地将以下内容添加到 Page_Load 事件中,这有助于初始加载,但回发后我仍然收到上述错误。 (不,这不在 !IsPostBack 中)

string connectionString = Encryption.Decrypt(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString, "XXXXXX");
        PeriodsDataSource.ConnectionString = connectionString;

【问题讨论】:

  • 你有没有尝试改变你的编码加密函数只包含像哈希字符串这样的字母数字。
  • @Dave3of5 感谢您的评论,但我不明白这有什么帮助,因为它仍然不是有效的 ConnectionString,因为它仍然需要在被引用之前被解密。
  • 你不能将加密的连接字符串包装到一个属性中,为页面解密一次吗?
  • @BFG 我认为你得到的错误是因为你的配置字符串中有特殊字符。顺便说一句,你知道你可以用微软的工具加密整个 web.config 文件吗?
  • @DarrenWood 原来是在 SqlDataSource 的 Init 事件中更新 SqlDataSource.ConnectionString 的一个非常简单的解决方案......请在此处查看我自己的问题以供将来参考。

标签: c# asp.net encryption


【解决方案1】:

这是我实施的解决方案。

asp:SqlDataSourceConnectionString%$ 字符表示它是一个表达式并因此被评估。我们可以创建自己的自定义表达式。

创建一个像这样扩展ExpressionBuilderclass

namespace YourNameSpace
{
    [ExpressionPrefix("EncryptedExpressionStrings")]
    public class EncryptedConnectionStringExpressionBuilder : ExpressionBuilder
    {
        private static string DecryptConnectionString(string cipherText)
        {
            return Encryption.Decrypt(cipherText);
        }
        public static ConnectionStringSettings GetConnectionStringSettings(string connectionStringName)
        {           
            return ConfigurationManager.ConnectionStrings[connectionStringName];
        }
        public static string GetConnectionString(string connectionStringName)
        {
            string decryptedConnectionString = null;
            System.Web.Caching.Cache connectionStringCache = new System.Web.Caching.Cache();
            if (connectionStringCache["connectionString"] == null)
            {
                ConnectionStringSettings settings = GetConnectionStringSettings(connectionStringName);
                decryptedConnectionString = DecryptConnectionString(settings.ConnectionString);
                connectionStringCache.Insert("connectionString", decryptedConnectionString);
            }
           else
           {
               decryptedConnectionString = (string)connectionStringCache["connectionString"];
            }
            return decryptedConnectionString;
        }
        public static string GetConnectionStringProviderName(string connectionStringName)
        {
            ConnectionStringSettings settings = GetConnectionStringSettings(connectionStringName);          
            return settings.ProviderName;
        }
        public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
        {
            Pair pair = DirectCast<Pair>(parsedData);
            string text = pair.First.ToString();
            if (Convert.ToBoolean(pair.Second))
            {
                return new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(base.GetType()), "GetConnectionString", new CodeExpression[] { new CodePrimitiveExpression() { Value = text } });
            }
            else
            {
                return new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(base.GetType()), "GetConnectionStringProviderName", new CodeExpression[] { new CodePrimitiveExpression() { Value = text } });
        }
        static T DirectCast<T>(object o) where T : class
        {
            T value = o as T;
            if (value == null && o != null)
            {
                throw new InvalidCastException();
            }
            return value;
        }
    }

你必须在web.config中声明新的自定义ExpressionBuilder

<compilation>
    <expressionBuilders>
        <add expressionPrefix="EncryptedExpressionStrings" type="YourNameSpace.EncryptedConnectionStringExpressionBuilder"/>
     </expressionBuilders>
</compilation>

你声明你的connectionString是加密的

<connectionStrings>
    <add name="EncryptedSqlDBConnectionString" connectionString="nWCfxsad8lkdyLWERODVxd3Ox..."
</connectionStrings>

然后您在 web.config 中为您的自定义 ExpressionBuilder 声明前缀的名称,并在 asp:SqlDataSource 中声明您的 ConnectionString 的名称

<asp:SqlDataSource runat="server" ID="YourID" ConnectionString="<%$ EncryptedExpressionStrings:EncryptedSqlDBConnectionString %>" SelectCommand="SELECT * FROM YourDBTable" />

这意味着您可以加密web.config 中的连接字符串,并且仍然评估asp.SqlDataSource connectionString

【讨论】:

    【解决方案2】:

    原来是在SqlDataSource的Init事件中更新SqlDataSource.ConnectionString的一个非常简单的解决方案,如下:

        protected void SqlDataSource_Init(object sender, EventArgs e)
        {
            string connectionString = Encryption.Decrypt(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString, "XXXXXX");
            SqlDataSource.ConnectionString = connectionString;
        }
    

    【讨论】:

      猜你喜欢
      • 2011-09-02
      • 1970-01-01
      • 1970-01-01
      • 2010-12-14
      • 2012-06-18
      • 2012-05-31
      • 1970-01-01
      • 1970-01-01
      • 2011-08-19
      相关资源
      最近更新 更多