Introduction
A while ago, I had to make a web page with lots of sensitive customer details in a GridView
on an ASP.NET page. I thought this is really bad, what happens if this data gets screen scraped by some nasty web bot that happens to match on email Regular Expressions? So I had a think, and an investigation into MSDN. And have come up with what I think is a nice solution.
The Basic Idea
The System.Text
namespace has an ASCII encoding, and there is also a System.BitConvertor
, so I thought about it. And thought I could actually encode the sensitive data using this method and store the ASCII / BitConverted data in the server requested HTML. Then, use JavaScript to reverse this process when the page is first loaded. That is what is presented in this article.
Probably the easiest way to get this is to look at the code.
Code
It's all in one web form, .. Nice and easy
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Simple web encryption</title>
<style type="text/css">
body
{
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
text-decoration: none;
position: relative;
color: #000000;
margin : 0px;
overflow-x : hidden;
width: 100%;
}
</style>
<script language="javascript">
function decode(ServerEncoded)
{
var res = "";
for (i=0; i < ServerEncoded.length;)
{
var letter = "";
letter = ServerEncoded.charAt(i) + ServerEncoded.charAt(i+1)
res += String.fromCharCode(parseInt(letter,16));
i += 2;
}
return res;
}
function GetEmailAndDecode() {
var txtSvrEncr = document.getElementById('txtServerEncrypted');
var txtJSDecr = document.getElementById('txtDecrypted');
txtJSDecr.value = decode(txtSvrEncr.value);
var txtAllTog = document.getElementById('txtAllTogether');
txtAllTog.value = decode(txtAllTog.value);
}
</script>
</head>
<body onload="GetEmailAndDecode();">
<form id="form1" runat="server">
<div>
<h1>Simple ASP .NET data protection</h1>
<p>
This simple web page contains a method
for keeping sensitive data (such as emails) safe, by
employing server side encryption and client side decryption.
It could be used for any data
I am using emails, but it could be applied to anything. You choose.
<br/>
<br/>
We all have emails these days, and this is somepeople
main contact detail. As such dont
we all deserve to have this one detail kept secret
from web bots that screen scrape web sites
looking for emails. This is what is done,
its easy just match an email regular expression and
away you go. They would easily be able to pull out
something like myname@hotmail.com
<br/>
<br/>
What this piece of codebehind stuff and javascript (in this page)
will show, is how to encrypt
a users email before sending the page to the client.
And then use javascript to decrypt it
back to an email again. The great part is that
the actual HTML code doesnt contain the email
at all, so the nasty web bot cant get the users personal
information out of the page. Ha Ha.
<br/>
<br/>
<br/>
<br/>
<b><asp:Label ID="Label1" runat="server"
Text="Normal email (BAD, web bot could grab this)">
</asp:Label></b>
<br/>
<br/>
<asp:TextBox ID="txtRawEmail" runat="server"
Width="357px">myname@hotmail.com</asp:TextBox>
<br/>
<br/>
<br/>
<br/>
<b><asp:Label ID="Label2" runat="server"
Text="Server side encrypted email / No javascript decryption...yet">
</asp:Label></b>
<br/>
<br/>
<asp:TextBox ID="txtServerEncrypted" runat="server"
Width="357px"></asp:TextBox>
<br/>
<br/>
<br/>
<br/>
<b><asp:Label ID="Label3" runat="server"
Text="Javascript decryption, from Server side encrypted email"></asp:Label></b>
<br/>
<br/>
<asp:TextBox ID="txtDecrypted" runat="server"
Width="357px"></asp:TextBox>
<br/>
<br/>
<br/>
<br/>
<b><asp:Label ID="Label4" runat="server"
Text="Putting it all together. Server side encrypted email /
Javascript decryption. Ha Ha web bot"></asp:Label></b>
<br/>
<br/>
<asp:TextBox ID="txtAllTogether" runat="server"
Width="357px"></asp:TextBox>
</p>
</div>
</form>
</body>
</html>
Default.aspx.cs
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
#region Email Encryption
if (Request.Browser.JavaScript)
{
txtServerEncrypted.Text = System.BitConverter.ToString(
System.Text.ASCIIEncoding.ASCII.GetBytes(
(txtRawEmail.Text))).Replace("-", "");
txtAllTogether.Text = System.BitConverter.ToString(
System.Text.ASCIIEncoding.ASCII.GetBytes(
(txtRawEmail.Text))).Replace("-", "");
}
else
{
txtServerEncrypted.Text = txtRawEmail.Text;
txtAllTogether.Text = txtRawEmail.Text;
}
#endregion
}
}
So How Does it Work
Well, what actually happens is very simple. Firstly, the server obfuscates the data, then the client-side JavaScript de-obfuscates it. But this means that the sensitive data is never actually within the source document in a format that a web bot can grab.
Let's have a look at the source file.
The value of the field txtAllTogether
is just ASCII text. However, if we then look at the rendered output for this page, we can see that the data has been de-obfuscated using client-side JavaScript. This will work with any data at all. I just chose email, as it's the most obvious form of data that should be kept private.
The attached project contains a single page, which has four text fields on it:
- The raw data
- The server side ASCII / BitConverted data
- The server side ASCII / BitConverted data through JavaScript
- Putting it all together in one textbox
What Do You Think?
That's it. I would just like to ask, if you liked the article, please vote for it.
Conclusion
I have quite enjoyed constructing this article. I hope it helps someone the way it has helped me.
History
- v1.1: 30/01/07: Changed wording from encryption to obfuscation, thanks to Jan Seda. He is actually correct. Well done, Jan.
- v1.0: 30/01/07: Initial issue.