您的位置:首页 > 编程语言 > ASP

ASP.NET中的加密与解密 【分析总结】ASP.NET中的状态管理原理

2012-03-27 14:26 471 查看

ASP.NET中的加密与解密

在ASP.NET中设计两个方面的加密和解密:一个是针对配置文件中配置节的加密和解密,另外一个是针对ASP.NET中数据的加密和解密。

在 .NET 中,加密和解密的技术可以分为两种。一种是加密和解密使用同样的密钥和算法,我们称之为密钥加密或者对称加密,这个方法的特点是非常快。另外一种加密方式为公钥加密或者成为非对称加密,这种加密算法对于加密和解密使用不同的密钥,通常有连个密钥A和B,使用密钥A加密数据得到密文,只有密钥B可以进行解码操作;而使用密钥B加密数据得到密文,只有密钥A可以解密。这两个密钥分别称为四要和公钥。非对称加密强度大,但是处理速度比较慢。

与此相关还有两个概念:数字签名散列。公钥算法还可用于构成数字签名,用来验证信息发送方的身份(如果您信任发送方的密钥)并帮助保护数据的完整性。散列算法将任意长度的二进制值映射为固定长度的较小二进制值,这个小的二进制值成为散列之。散列函数来确保消息的完整性。

在ASP.NET中的很多加密和解密都要依赖于密钥,密钥保存在配置文件的machineKey里面。默认情况下,ASP.NET通过动态生成来创建网站所使用的密钥,如果单台服务器当然没问题,但是如果网站采用多台服务器负载均衡,machineKey还采用动态生成的方式,那么,每台服务器上的machineKey的值不一致,会导致加密出来的结果也不一致,不能共享验证和ViewState,所以对于多台服务器负载均衡的情况,一定要在每台站点配置相同的machineKey。

ASP.NET中,machineKey用于以下三种用途:

  ·使用 forms authentication时的cookie数据的加密和解密,以确保这部分数据不会被篡改。

  ·viewstate数据的加密和解密,以确保这部分数据不会被篡改。

  ·使用进程外session(out-of-process session)时,对话状态标识进行验证。

(具体参见MSDN:http://msdn.microsoft.com/zh-cn/library/w8h3skw9(v=vs.80).aspx

【分析总结】ASP.NET中的状态管理原理

HTTP协议是介于请求、响应的断开时网络协议,与连接式的网络协议不同,例如,与我们熟悉的TCP协议相比,客户端与服务器并没有持续的连接存在,在每一次会话之后,连接都会被断开,在下一次请求的时候客户端会重新与服务器建立连接进行会话。那么,服务器如何来跟踪客户端,在断开的轻快下,客户端又如何与服务器端保持会话呢?

为了解决这个问题,在网站开发中,提供了大量的状态管理技术来解决这个问题,在ASP.NET中,还提供了一些专用的技术,使得我们更加轻松的完成状态管理服务。

·首先我们可以考虑form表单中提供的隐藏域。顾名思义,隐藏域就是表单中看不到的输入项,他必须配合表单使用。虽然看不到,但是,在提交表单的时候,隐藏域中得信息将随着表单一起被发送到服务器。隐藏域的使用方法如下:

<form method="post" action="hidden.aspx" id="form1">
...
<input type="hidden" id="HiddenField1" name="HiddenField1" value="DebugLZQ"/>
...
</form>

复制代码

在ASP.NET中,可以通过HiddenField这个服务器控件来生成上述的HTML,这样我们就可以在服务器上,通过面向对象的方式来获取网页中得隐藏域。

this.HiddenField1.value=this.TextBox1.Text;


在默认轻快下,ASP.NET表单将会提交到本页面,所以,在提交表单的时候,保存在客户端隐藏域中得信息将会发送回服务器。由于轻轻参数的name将会与服务器上页面对象中隐藏域控件的id相匹配,这样,在下一次请求的时候,在服务器上,我们就可以通过隐藏域控件的属性获得上一次请求中保存在隐藏域中得值。

this.TextBox1.Text=this.HiddenField1.value;


存在的问题:影藏域存在于网页中得Form表单,当页面关闭的时候,隐藏域中得信息将会丢失。所以不适合需要长期有效的状态管理。

·为了能够更加长久地保存用户会话的状态信息,Cookie被Netscape公司引入网站开发中。

传统上,网站是基于广播模式的,也就是说,所有的用户看到的内容都是一样的,,如果对用户提供一对一的服务,就必须能够从用户的请求中去别处不同的用户。虽然通过隐藏域也能部分完成这个需求,但是,当用户关闭浏览器的时候,隐藏域中保存的信息将会丢失,不能长久保存。Cookie允许用户将自己的状态信息以名值对的形式保存在客户端。在Cookie有效的情况下,在用户每次向这个服务器发出请求的时候都会自动附加在请求中,同时还允许设置Cookie保存在客户端的时间,以便于在用户关闭浏览器之后,还能继续保存状态信息。

在HTTP协议中,通过在服务器的回应中增加Set-Cookie的回应头,可以指示客户端保存Cookie。

浏览器会在特殊的位置来保存Cookie的内容,Cookie的内容不会在页面上显示出来,非常适合隐藏地保存状态信息。

在浏览器保存有Cookie的情况下,在以后的请求中,浏览器将会以请求头的形式自动附加这个Cookie中保存的信息,以名值对的形式发送到服务器。

这样,服务器就可以获得从前保存的状态信息了。

在ASP.NET中,服务器通过HttpCookie数据类型来处理在回应中生成Set-Cookie头和在请求中的Cookie信息的问题。

public sealed class HttpCookie


配合HttpCookie,在HttpResponse中,通过Cookie集合属性来表示准备生成回应中Set-Cookie的HttpCookie集合。这样,在服务器上,指示客户端生成Cookie的代码如下所示:

HttpCookie cookie=new HttpCookie("DebugLZQ");
cookie.Value=this.TextBox1.Text;

this.Reponse.Cookies.Add(cookie);

复制代码

对于请求中附带的Cookie信息,HttpRequest通过其Cookies集合属性表示为对象的形式,由于浏览器的请求中可能附带有多个Cookie参数,可以通过Cookie的名字来获取对应的Cookie参数。

HttpCookie cookie=new HttpCookie("DebugLZQ");
if(cookie!=null)
{
this.Label1.Text=cookie.Value;
}

复制代码

在默认情况下创建的Cookie,将保存在浏览器的Cookie容器中,当浏览器关闭时,Cookie将一同被销毁。Cookie的Expires属性表示Cookie的过期时间。这是一个绝对过期时间,以格林威治标准时间的格式表示,到达这个时间之后,Cookie将会失效。为了能过长期使用保存在Cookie中的信息,可以将Cookie的Expires属性设置为未来的一个更长的时间,在大道这个时间之前,Cookie将一直有效。例如,可以通过如下的语句将Cookie设置保存10分钟。

cookie.Expires=DateTime.Now.AddMinutes(10.0);


注意,如果没有设置过期时间,Cookie将会保存到浏览器关闭为止。

可是,浏览器关闭之后,Cookie将保存在那里了?他是如何做到再次打开浏览器时,依然能够取得Cookie中的值呢?

在设置过期时间之后,浏览器会将这个Cookie保存在一个特定的文件夹中,Cookie文件时一个文本格式的文件。根据RFC2109的描述,每个客户端最多保存300个Cookie,对于每个站点来说最多20个Cookie(实际上多数浏览器现在都比这个多,比如Firefox是50个),每个cookie最多4K,注意这里的4K根据不同的浏览器可能不是严格的4096。

·我们也可以通过在URL地址中嵌入信息来实现状态管理,由于在向服务器发出请求的时候,URL地址将作为请求的一部分发送到服务器,这样,可以从中提取出保存的信息。需要在URL地址中保存信息的时候,通过将信息以特殊的格式插入到URL地址中完成。

·使用隐藏域可以在表单中传递大量的数据,但是,直接保存在隐藏域中的信息必须是字符串形式的数据,这是HTML页面的字符性质决定的。在ASP.NET服务器端处理的是以对象为表示形式的数据,如果这些对象可以被保存以便在后继的访问中使用,将大大方便服务器端的程序设计。在ASP.NET中,提供了基于隐藏域的增加对象序列化和反序列化支持的状态管理机制,通过将服务器端的可序列化对象序列化为字符串的形式,然后,以隐藏域的形式保存在也卖弄的表单中,一般在后继的请求中发送回服务器,最后通过反序列化操作还原为原来的对象,在ASP.NET中这个技术被称为视图状态ViewState

·视图状态ViewState为开发人员带来便利,但是巨大的视图状态在服务器和浏览器之间的往返传递也带来了繁重的网络压力,有的时候我们会禁用也卖弄的视图状态来提高访问的效率。

由于有些信息对付控件来说非常重要,所以,在禁用ViewState后,会造成有些控件功能的彻底失效,比如GridView的分页功能。从ASP.NET 2 0开始,通过控件状态来提供一种比视图状态更加安全的控件状态ControlState的管理管理机制。控件状态的使用类似于视图状态,但是,即使用户关闭视图状态之后,也会仍然有效。

类似于视图状态的LoadViewState和SaveViewState方法,控件状态也是提供了一对这样的方法,方法名称分别为LoadControlState和SaveControlState,兵器也是在Control基类中提供。

要使用控件状态,首先需要在也卖弄上注册需要使用的控件状态。这个工作一般在控件的Init中进行,方法的参数就是要注册的控件对象。

protected override void OnInit(EventArgs e)
{
base.OnInit(e);
page.RegisterRequiresControlState(this);
}

复制代码

然后,在控件中使用LoadViewState和SaveViewState完成控件状态的加载和保存即可。

·应用程序状态HttpApplicationState的机制是比较简单的,这是一个服务器端的全局的状态管理。因为是服务器端的全局状态管理,所以,不在涉及也卖弄和请求的处理过程,也不需要区分不同的会话或者用户。为了方便保存多个不同的状态,应用程序状态Application派生自NameObjectCollectionBase,允许用户通过一个字符串的名字来保存或提取相应的对象。

应用程序状态管理对象可以通过上下文对象获取到,他的定义如下:

public HttpApplicationState Application{get;}


其中,HttpApplicationState的定义如下:

public sealed class HttpApplicationState:NameObjectCollectionBase


对于引用程序状态对象来说,由于所有的请求都可能需要访问这个对象,为了解决并发访问的问题,同时还提供了线程的同步机制,通过来同步对于这个集合的访问。

public void Lock();

public void UnLock();

复制代码

HttpApplicationState类使用AllKeys和Count属性以及Add、Clear、Get、GetKey、Remove、RemoveAt和Set方法来自动锁定和解锁。但是,如果需要对保存在全局应用程序状态中的数据进行连续多次的访问,通过显式的Lock进行加锁和UnLock进行解锁有助于提高访问效率。

对于一个网站来说,存在一个HttpApplicationState对象管理状态,这个对象随着网站的启动而穿件,当网站关闭的时候才会释放,因此,通过Application保存的状态信息会伴随整个网站的生命周期,在不适用的时候,一定要及时释放所用的空间。

·Session是一个历史悠久的状态管理技术,从ASP时代开始,就称为了Web开发不可或缺的基本状态管理技术。

对于无状态的HTTP来说,Session是一个服务器端的状态管理方案,这个方案的特点在于每个客户端都可以将实际的数据保存在服务器上,对于客户端的数据,会生成一个对应的唯一的key。在服务器端保存数据之后,将用于取得所保存数据的key发送到客户端。在后继的请求中,客户端将这个保存在客户端的key发送回服务器端,在服务器上通过这个key来取得相应的数据。通常,我们称这个key为SessionID。Session的工作原理如下:



在一般轻快下,这个SessionID以Cookie的形式保存在浏览器中,在不适用Cookie的情况下,也可以将这个SessionID嵌入到访问网站的URL地址中(前面讲过)。

在页面对象或者HttpContext对象汇总,都有一个名为Session的属性,在一次会话中,他们引用的是同一个对象,定义如下:

public HttpSessionState Session{get;}


在Sesion中,我们通常使用下面的方法来进行状态管理:

public void Add(string name,Object value)

public void Remove(string name);

public void Clear();

public void Abandon();

复制代码

这个HttpSessionState来自于SessionStateModule。在每次请求处理过程中,HttpApplication的请求的处理管道中会检查当前请求的处理程序是否实现了接口IRequiresSessionState,如果实现的话,那么SessionStateModule将为这个请求分配HttpSessionState。

需要注意的是,只有执行下面这样的代码片段后,才可以认为Session会话开始。

Session[“DebugLZQ”]=”some data”;


Session字典通常包含Object类型,要向后读取数据,需要将返回的值转为为更具体的类型。

string data=Session[“DebugLZQ”] as string;


Session_OnEnd事件标志着会话的结束,并用于执行中止该会话所需的所有清除代码。

如果会话超时或被放弃,下次访问无状态应用程序时,其会话ID不会发生改变。进过设计后,即使会话状态过期,会话ID也能持续到浏览器会话结束。也就是说,只要浏览器实例相同,就始终使用同一个会话ID表示多个会话。

对于Session来说,关键的问题在于Session过期指的是某个会话整个Session的过期,并不针对其中某个数据的过期,要么整个Session过期后丢弃掉,要么所有的数据都被保留下来,在每一次请求的时候都会被加载到内存中,这可能会造成内存的浪费。所以,在使用Session的时候,我们必须要谨慎选择保存的数据。

·HttpContext状态可能是所有状态管理中最简单的状态管理,也是最有效的状态管理方式,HttpContext基于HttpApplication的处理管道,由于HttpContext对象贯穿整个处理过程,所以,可以从HttpApplication处理管道的前端将状态数据传递到管道的后端,完成状态的传递任务。

在HttpContext中通过Items属性允许我们将需要传递的数据进行存取,这个属性的定义如下:

public IDictionary items{get;}


可以看到这是一个字典,我们可以通过键值对的形式来使用它。

·缓存管理Cache是ASP.NET中更加强大的状态管理。这是在 ASP.NET中唯一可以根据服务器的使用情况,动态管理内存使用的状态管理干干。允许我们针对每一个缓存的数据,单独设置数据的有效条件,使得内存的使用效率最大化。Cache属于公共的状态管理,我们通过每个缓存数据的键值字符串来区分缓存的数据(不详细解释了~)。

·Memcached是dangga.com开发的一套分布式内存对象缓存系统。Memcached是分布式的,基于网络连接(当然他也可以使用localhost)方式完成服务,本身它是一个独立于应用的程序或守护进程。

Memcached在很多时候都是作为数据库前端Cache使用的。因为他比数据库少了很多SQL解析、磁盘操作等开销,而且它是使用内存来管理数据的,所以他可以提供比直接读取数据库更好的性能。在大型系统中,访问同样的数据时很频繁的,Memcached可以大大降低数据库压力,是系统执行效率提升。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: