Web编程过程中,存在着很多安全隐患。比如在以前的ASP版本中,Cookie为访问者和编程者都提供了方便,并没有提供加密的功能。打开IE浏览器,选择“工具”菜单里的“Internet选项”,然后在弹出的对话框里单击“设置”按钮,选择“查看文件”按钮,在弹出的窗口中,就会显示硬盘里的缓存数据,其中就有大量的Cookie文件。如图1所示。问题是,这样安全吗?

 

于是,我们会想到很多安全措施,比如使用SSL、建立网上银行一样的强认证方式等,但是,对于大部分网站而言,可能这些方法具有一定的困难性,因为要实现这些比较强的安全措施,最起码需要一台服务器,在经济上显然不是小数目。那么,有没有比较经济的方法来解决这类问题呢?答案是肯定的,现在.NET构架在System.Security.Cryptography命名空间里提供了许多加密类可以利用,包括安全的数据编码和解码以及散列法、随机数字生成和消息身份验证。下面,我们来看看几个比较典型的例子,以供参考。

实现ASP.net表单的安全提交

使用ASP.NET环境下的电子邮件功能,我们可以容易的实现发送电子邮件。可能我们会说,不用ASP.NET,直接使用HTML,也可以实现以上功能。其实,这是完全不一样的:使用HTML,用户提交信息的时候,是调用客户端的邮件收发软件,使用用户的邮箱发送表单信息,如果用户没有邮箱或者用户没有邮件收发软件,就不能提交信息;而采用ASP.NET,可以使用服务器端(程序设计者)提供的邮箱和SMTP服务器,也不需要客户安装邮件收软件,一切都直接在服务端完成,显然更加适合我们的要求。现在,我们就来看以上功能的代码实现。首先,我们来看网页界面实现的关键代码:

<Form id="form1" runat="server">

姓名: <asp:TextBox id="txtFname" runat="server" />

地址: <asp:TextBox id="txtAddr" runat="server" />

内容: <asp:TextBox id="txtContent" runat="server" />

<asp:Button id="btnEmail" Text="提交" onclick="doEmail" runat="server" />

</Form>

以上只是很简单的几个提交项,在实际中,我们可以根据需要增加。还是根据上述例子,因为需要用到电子邮件功能,所以,我们需要引入Email名字空间:<%@ Import Namespace="System.Web.Mail" %>;然后,我们来实现按钮btnEmail的点击事件:

Sub doEmail(Source as Object, E as EventArgs)

Dim sMsg as String

sMsg+="提交信息:" & vbcrlf

sMsg+="姓名 " & txtFname.Text & vbcrlf

sMsg+="地址: " & txtAddr.Text & vbcrlf

sMsg+="内容: " & txtContent.Text & vbcrlf

Dim objEmail as New MailMessage

objEmail.To="whpub@tom.com"

objEmail.FROM="from@tom.com"

objEmail.SUBJECT="提出意见"

objEmail.BODY=sMsg

objEmail.BodyFormat = MailFormat.Text

SmtpMail.SmtpServer ="mail.tom.com "

SmtpMail.Send(objEmail)

End Sub

以上我们用很简单的举例介绍了安全实现表单提交。实际使用中,我们可以在以上代码中加入附件提交等功能完善我们的程序。

Cookie的安全问题

还是接我们最初提到的一个话题。在ASP.net编程中,Cookie数据包含在HTTP请求和响应的包头里透明地传递,也就是说聪明的人是能清清楚楚看到这些数据的。其次,Cookie数据以Cookie文件格式存储在浏览者计算机的cache目录里,其中就包含有关网页、密码和其他用户行为的信息,那么只要进入硬盘就能打开Cookie文件,所以实际编写中,我们不要将敏感的用户数据存放在Cookie中,要么就通过加密将这些数据保护起来。使用一种算法不仅要考虑加密强度,还要考虑其他因素,比如Cookie的大小要限制在4KB。一般来说,由于加密后的Cookie数据将变大,并且密钥越大,加密后的数据就越大,就会占有更多的服务器资源,进而减慢整个站点的访问速度。

另外,我们不能直接修改一个Cookie,应该是创建一个同名的 Cookie,并把该 Cookie 发送到浏览器,覆盖客户机上旧的 Cookie。同样,我们无法直接将其删除一个Cookie,可以通过修改一个Cookie达到让浏览器删除Cookie的目的,修改Cookie的有效期为过去的某个时间,当浏览器检查 Cookie 的有效期时,就会删除这个已过期的 Cookie

通过web.config进行站点配置

使用ASPPHPJSP编写代码时,虽然我们编写了用户登录,注册,验证页面,但是效果总是不理想,因此,站点安全性总是需要花费不少的时间,而且往往会造成顾此失彼的问题。但是,在.NET环境下,这个问题就很容易了,而问题的关键是要充分理解Web.config文件。Web.config文件的相关选项具体含义如下:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<system.web>

<!-- 动态调试编译

设置 compilation debug="true" 以将调试符号插入到编译页中。因为这将创建执行起来较慢的大文件,所以应该只在调试时将该值设置为 true,而所有其他时候都设置为false

-->

<compilation defaultLanguage="vb" debug="true" />

 

<!-- 自定义错误信息

设置 customErrors mode="On" "RemoteOnly" 以启用自定义错误信息,或设置为 "Off" 以禁用自定义错误信息。可以为每个要处理的错误添加 <error> 标记。

-->

<customErrors mode="RemoteOnly" />

 

<!-- 身份验证

设置应用程序的身份验证策略。可能的模式是 /Windows/”、/Forms/”、/Passport/”和 /None/

-->

<authentication mode="Windows" />

 

<!-- 授权

此节设置应用程序的授权策略。可以允许或拒绝用户或角色访问应用程序资源。通配符:"*" 表示任何人,"?" 表示匿名(未授权的)用户。

-->

<authorization>

<allow users="*" /> <!-- 允许所有用户 -->

 

<!-- <allow users="[逗号分隔的用户列表]"

roles="[逗号分隔的角色列表]"/>

<deny users="[逗号分隔的用户列表]"

roles="[逗号分隔的角色列表]"/>

-->

</authorization>

 

<!-- 应用程序级别跟踪记录

应用程序级别跟踪在应用程序内为每一页启用跟踪日志输出。

设置 trace enabled="true" 以启用应用程序跟踪记录。如果 pageOutput="true",则跟踪信息将显示在每一页的底部。否则,可以通过从 Web 应用程序根浏览 "trace.axd" 页来查看应用程序跟踪日志。

-->

<trace enabled="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" />

 

<!-- 会话状态设置

默认情况下,ASP.NET 使用 cookie 标识哪些请求属于特定的会话。如果 cookie 不可用,则可以通过将会话标识符添加到 URL 来跟踪会话。若要禁用 cookie,请设置 sessionState cookieless="true"

-->

<sessionState

mode="InProc"

stateConnectionString="tcpip=127.0.0.1:42424"

sqlConnectionString="data source=127.0.0.1;user id=sa;password="

cookieless="false"

timeout="20"

/>

 

<!-- 全球化

此节设置应用程序的全球化设置。

-->

<globalization requestEncoding="utf-8" responseEncoding="utf-8" />

</system.web>

</configuration>

下面,我们来看一个具体的设置实例,为了防止用户没有经过验证就访问站点,我们的处理方法是:当用户没有通过验证的时候点击任何页面将会直接跳到Login.aspx页面,具体代码如下:

<authentication mode="Forms">

<forms name="yourAuthCookie" loginUrl="login.aspx" protection="All" path="/" />

</authentication>

<authorization>

<deny users="?" />

</authorization>

但是这样会产生一个问题,那就是如果我的站点有一些信息是可以让任意用户随意访问的,比如站点简介、使用说明等。不同级别的处理也是一个比较麻烦的问题,如果按照上面的处理方法,肯定很麻烦。在ASP.NET中也会有相应的解决办法,下面的代码可以实现匿名用户访问Test.aspx页面,具体如下:

<location path="test.aspx">

<system.web>

<authorization>

<allow users="?" />

</authorization>

</system.web>

</location>

.net加密的典型应用

在网站上建立数据库时,保护用户的信息安全是非常必要的。多数用户不愿意让别人知道自己的信息,同时网管也不想因为安全问题而丢失网站的信誉。无论对于谁,安全问题都是非常重要的。简单的讲,就是将用户提供的口令加密之后,然后让它和存放于系统中的数据比较,如果相同,则通过验证。目前有两种加密方法:对称加密(或称私有密钥)和非对称加密(或称公共密钥)。.NET构架从基本的SymmetricAlgorithm类中,扩展了四种算法,具体如下:

·System.Security.Cryptography.DES

·System.Security.Cryptography.TripleDES

·System.Security.Cryptography.RC2

·System.Security.Cryptography.Rijndael

ASP.NET在名字空间System.Web.Security中包含了类FormsAuthentication,其中有一个方法HashPasswordForStoringInConfigFile,这个方法可以将用户提供的字符变成乱码,然后存储起来,甚至可以存储在cookies中。另外,在我们的网页中有各种密码需要保护,把密码直接放在数据库或者文件中存在不少安全隐患,所以密码加密后存储是最常见的做法。在ASP.NET中实现加密非常容易。.NET提供了HashPasswordForStoringInConfigFile方法可直接使用MD5SHA1算法。例子如下,首先Encrypting.aspx文件:

<%@ Page language="c#" Codebehind="encrypting.aspx.cs" AutoEventWireup="false" Inherits="encrypting.encrypting" %>

<HTML>

       <HEAD>

              <meta name="GENERATOR" Content="Microsoft Visual Studio 7.0">

              <meta name="CODE_LANGUAGE" Content="C#">

       </HEAD>

       <body>

              <form method="post" runat="server" ID="Form1">

                     <p><FONT face="宋体"></FONT>&nbsp;</p>

                     <p><asp:TextBox id="TextBox1" runat="server"></asp:TextBox><asp:Button id="Button1" runat="server" Text="MD5加密"></asp:Button></p>

                     <p><asp:TextBox id="TextBox2" runat="server"></asp:TextBox><asp:Button id="Button1" runat="server" Text="SHA1加密"></asp:Button></p>

                     <p>加密后的字串1:<asp:Label id="MD5" runat="server"></asp:Label></p>

                     <p>加密后的字串2:<asp:Label id="SHA1" runat="server"></asp:Label></p>

              </form>

       </body>

</HTML>

以下是实现加密的代码encrypting.cs摘要:

……

              public void Button1_Click (object sender, System.EventArgs e)

              {

//取出MD5

                     MD5.Text = FormsAuthentication.HashPasswordForStoringInConfigFile(TextBox1.Text,"md5");

//可以取出SHA1

SHA1 use  FormsAuthentication.HashPasswordForStoringInConfigFile(TextBox2.Text,"SHA1");}

              }

       }

}

……

       结合以上典型例子,通过简单的两句代码,我们就可以实现以前需要几十行甚至上百行代码的功能,这也是ASP.net吸引人之处。类似的操作还有很多,综合运用,我们就会对ASP.net中的一些安全编程一定有了一个初步的了解。当然,实际使用中,我们还需要结合System.Security.Cryptography命名空间,做一些更加有益的尝试,从而编写出更加健壮、安全的代码。


本文转载:CSDN博客