ASP.NET 查询字符串加密






3.90/5 (28投票s)
明文查询字符串对您的 Web 应用程序构成潜在的安全威胁。因此,查询字符串应始终加密。
引言
使用查询字符串从浏览器向服务器发送数据是一种广泛采用的方法。允许 Web 应用程序的访问者修改以明文形式传输的查询字符串,无疑是一种潜在的安全威胁。
因此,我鼓励开发人员加密查询字符串,即使它们不包含机密数据。但是,我知道仍然可以篡改加密的查询字符串,但通过适当的异常处理,这是无害的。
背景
为了使本文简单易懂,我使用了可破解的加密方法(DES 编码),尽管任何最先进的加密方法都可以轻松应用于给定的示例。
使用代码
那么,让我们开始吧。所提供解决方案的主要部分是一个 HttpModule
,它解密查询字符串,从而为页面请求提供普通的未加密查询字符串。
using System;
using System.Web;
using System.Web.Configuration;
namespace HelveticSolutions.QueryStringEncryption
{
/// <summary>
/// Http module that handles encrypted query strings.
/// </summary>
public class CryptoQueryStringUrlRemapper : IHttpModule
{
#region IHttpModule Members
/// <summary>
/// Initialize the http module.
/// </summary>
/// <param name="application">Application,
/// that called this module.</param>
public void Init(HttpApplication application)
{
// Attach the acquire request state event
// to catch the encrypted query string
application.AcquireRequestState += application_AcquireRequestState;
}
public void Dispose()
{}
#endregion
/// <summary>
/// Event, that is called when the application acquires the request state.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void application_AcquireRequestState(object sender, EventArgs e)
{
// Get http context from the caller.
HttpApplication application = (HttpApplication) sender;
HttpContext context = application.Context;
// Check for encrypted query string
string encryptedQueryString = context.Request.QueryString["request"];
if (!string.IsNullOrEmpty(encryptedQueryString))
{
// Decrypt query strings
string cryptoKey = WebConfigurationManager.AppSettings["CryptoKey"];
string decryptedQueryString =
CryptoQueryStringHandler.DecryptQueryStrings(encryptedQueryString,
cryptoKey);
context.Server.Transfer(
context.Request.AppRelativeCurrentExecutionFilePath +
"?" + decryptedQueryString);
}
}
}
}
正如您可能注意到的,如果当前请求存在加密的查询字符串,该模块将自动终止当前页面的执行,并在服务器上内部启动新的请求执行。
下一步是在 web.config 文件中注册 HttpModule
<httpModules>
<add name="CryptoQueryStringUrlRemapper"
type="HelveticSolutions.QueryStringEncryption.CryptoQueryStringUrlRemapper"/>
</httpModules>
最后但并非最不重要的一点,不要忘记在将其发送回服务器之前加密查询字符串。
private void PrepareSendButton()
{
NameValueCollection queryStrings = new NameValueCollection();
queryStrings.Add("param1", "Test1");
queryStrings.Add("param2", "Test2");
queryStrings.Add("param3", "Test3");
// Encrypt query strings
string encryptedString = CryptoQueryStringHandler.EncryptQueryStrings(
queryStrings, WebConfigurationManager.AppSettings["CryptoKey"]);
btnSendParams.PostBackUrl = string.Concat("~/Default.aspx?", encryptedString);
}
如本文前面所述,加密类可以轻松地替换为任何其他加密类。可以从上方下载一个完整的运行示例。
重要问题
CryptoQueryStringHandler
中的 DecryptQueryStrings
方法包含以下行
return Encryption64.Decrypt(encryptedStrings.Replace(" ", "+"), key);
出于未知原因,请求会将查询中的每个 '+' 字符替换为空字符。
历史
- 2008 年 4 月 30 日 - 第一个版本(已删除 -> 无法修改,无论出于何种原因……)。
- 2008 年 5 月 1 日 - 重新发布更新后的文章。
- 2008 年 5 月 8 日 - 为了支持 Session 数据,将
HttpModule
中的BeginRequest
事件更改为AcquireRequestState
。 - 2014 年 11 月 11 日 - 更正了命名空间