在ASP.NET中使用脚本代码保护功能
keywords: asp.net Scripting.Encoder IHttpModule
一、Microsoft Script Engine Version 5.0
C:/winnt/system32/scrobj.dll
一个简单示例:
Public Function EncodeScript() as string
Dim strScript As String = "<script language=""javascript"">document.write(fileurl2);</script>"
Dim myEncoder As New Scripting.Encoder
EncodeScript = myEncoder.EncodeScriptFile(".htm", strScript, 0, "")
End Sub
函数EncodeScript的返回值为:
<script language="JScript.Encode">#@~^IQAAAA==@#@&NG1Es+xDRS.kD+c0bVn;MV *I@#@&lwkAAA==^#~@</script>
可见,Scripting.Encoder可以很好的将javascript编码成不可人为识别的代码,供客户端IE执行。由此,我们可以考虑将ASP.NET
中的所有javascript脚步用这个技术来编码以达到代码保护的效果。
二、使用IHttpModule实现所有的脚本编码
1、使用vs2005创建一个asp.net项目, 将C:/winnt/system32/scrobj.dll添加到引用中(此项在COM标签中)
2、创建一个类ScriptEncodeStream用于在Respone出页面之前修改HTTP主体中javascript内容
public class ScriptEncodeStream : Stream
{
private Stream oStream;
private long position;
private Scripting.Encoder encoder;
public ScriptEncodeStream(Stream iStream)
{
oStream = iStream;
encoder = new Scripting.EncoderClass();
}
public override bool CanRead
{
get { return true;}
}
public override bool CanSeek
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override void Close()
{
oStream.Close();
}
public override void Flush()
{
oStream.Flush();
}
public override long Length
{
get { return 0; }
}
public override long Position
{
get { return position; }
set { position = value; }
}
public override long Seek(long offset, SeekOrigin origin)
{
return oStream.Seek( offset, origin );
}
public override void SetLength(long length)
{
oStream.SetLength( length );
}
public override int Read(byte[] buffer, int offset, int count)
{
return oStream.Read( buffer, offset, count );
}
public override void Write(byte[] buffer, int offset, int count)
{
string outStr;
outStr = UTF8Encoding.UTF8.GetString( buffer, offset, count );
int idxStart = outStr.IndexOf("<script language=/"javascript/">");
int idxEnd = -1;
while (idxStart >= 0)
{
idxEnd = outStr.IndexOf("</script>", idxStart);
string script = outStr.Substring(idxStart, idxEnd - idxStart + 9);
string scenc = encoder.EncodeScriptFile(".htm", script, 0, "");
outStr = outStr.Replace(script, scenc);
idxStart = outStr.IndexOf("<script language=/"javascript/">");
}
byte[] rData = UTF8Encoding.UTF8.GetBytes( outStr );
oStream.Write( rData, 0, rData.Length );
}
}
3、创建一个HttpModule类
public class ScriptEncodeHttpModule : IHttpModule
{
public ScriptEncodeHttpModule()
{
}
public void Dispose()
{
}
public void Init(HttpApplication app)
{
app.BeginRequest += new EventHandler(app_BeginRequest);
}
void app_BeginRequest(object sender, EventArgs e)
{
HttpResponse response = HttpContext.Current.Response;
if (response.ContentType == "text/html")
{
response.Filter = new ScriptEncodeStream(response.Filter);
}
}
}
4、注册httpModule
打开Web.Config文件,在<system.web></system.web>中插入如下代码:
<httpModules>
<add name="ScriptEncodeHttpModule" type="ScriptEncodeHttpModule" />
</httpModules>
5、创建一个测试页面test.aspx
在页面的html代码中,将如下javascript脚本插入到<head></head>中:
<script language="javascript">
var protectedfield = "my value";
function showfield()
{
alert(protectedfield);
}
</script>
将如下代码插入到<form></form>中:
<input type=button value=showfield οnclick="showfield();" />
6、编译,运行
在浏览器中输入[localhost:1346], 点击"showfield"按钮,
可以看见,javascript脚本的功能丝毫未变;另外的,查看一下页面的源代码,我们已经找不到
任何有用的javascript脚本代码信息了。