ASP 101 - Active Server Pages 101 - Web06
The Place ASP Developers Go!

Please visit our partners


Windows Technology Windows Technology
15 Seconds
4GuysFromRolla.com
ASP 101
ASP Wire
VB Forums
VB Wire
WinDrivers.com
internet.commerce internet.commerce
Partners & Affiliates














ASP 101 is an
internet.com site
ASP 101 is an internet.com site
IT
Developer
Internet News
Small Business
Personal Technology

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers

ASP 101 News Flash ASP 101 News Flash



 Top ASP 101 Stories Top ASP 101 Stories
The Top 10 ASP Links @ Microsoft.com
What is Adovbs.inc and Why Do I Need It?
An Overview of ASP.NET

QUICK TIP:
Using Quotes in Your SQL Commands
Show All Tips >>
ASP 101 RSS Feed ASP 101 Updates


ASP Authentication Using XOR Encryption

by Valko Yotov

Introduction

This article explains how to control application access by validating the user's login and password against a SQL 2000 database. Once validated, the user gets a one time pad Access Code generated by SQL 2000 server, which is different and unique for every login - Access Code changes on every user login - it is one time pad - OTP. Then the user's IP host address is encrypted using Access Code and simple XOR and saved in database (XOR-based OTPs are perfectly secure against cipher text-only cryptanalysis)..

On all restricted pages we include the access validation routine and if the user's IP does not match against the saved one, the user does not get access. None of the asp pages use sessions or cookies for communication.

Avoiding Session use drastically improves your web site performance, as does explicitly declaring variables you use in your asp pages. Therefore including the following 2 lines of code:

<%@ Language=VBScript enablesessionstate=false %>
<% Option Explicit %>

at the top of every asp page you write is well worth the effort.

The Access Code is transmitted over your application's restricted access pages in hidden form variable, and you just use a simple function to encrypt and compare current user's IP host address Access Code with that one created and saved in the database during login.

We generate the Access Code using SQL 2000 server uniqueidentifier data type - it stores 16-byte binary values that operate as globally unique identifiers (GUIDs). A GUID is a unique binary number; no other computer in the world will generate a duplicate of that GUID value.

Here is T-SQL code for generating our Access Code table:

CREATE TABLE [ACCESS_CODE] (
   [ACCESS_CODE_ID]  uniqueidentifier ROWGUIDCOL  NOT NULL ,
   [USER_ID] [int] NOT NULL ,
   [USER_HOST_IP] [nvarchar] (250) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
   CONSTRAINT [ACCESS_CODE_PK] PRIMARY KEY  CLUSTERED 
   (
      [ACCESS_CODE_ID]
   )  ON [PRIMARY] 
) ON [PRIMARY]
GO

Note that uniqueidentifier columns may contain multiple occurrences of an individual uniqueidentifier value, unless the UNIQUE or PRIMARY KEY constraints are also specified for the column. Also note ROWGUIDCOL property indicates that the uniqueidentifier values in the column uniquely identify rows in the table. The property does not do anything to enforce this, however. The uniqueness is enforced as specifying the PRIMARY KEY constraint for the column.

Other T-SQL code is self-describing. It creates database called MyLoginDB, table USER_ACCESS for user data, table ACCESS_CODE for Access Code and user's host IP address, populates 2 rows with test user's data, and then create the 4 stored procedures needed. Note the second one called sproc_CreateNewAccessId is used to create new Access Code. If an old Access Code already exists, sproc_CreateNewAccessId deletes Access Code first, then creates new one - unique for every user's login!

We have login.asp page, which validates user's email and password against the database. Function FncGetPass returns a recordset form database and if user's email exist and passwords match we give him access rights:

set rsPass = FncGetPass (strUserName,objConn)
if rsPass.bof and rsPass.eof then   'no data!
	boolEmailExists = false
else
	boolEmailExists = true
	strTemp = rsPass("USER_PASS")
	strUserId = rsPass("USER_ID")
	If strTemp = strPassword Then
		boolPassExists = true
	Else
		boolPassExists = false
	End If
end if

Both variables boolEmailExists and boolPassExists are set to true and then we call function FncCreateNewAccessId passing for argument already validated current user's id:

If boolEmailExists Then
   If boolPassExists Then
      strAccess = FncCreateNewAccessId (strUserId, objConn)

If for that user's id exist old Access Code FncCreateNewAccessId deletes Access Code first, then creates new one - unique for every user's login! FncCreateNewAccessId also returns strAccess variable, which is our GUID in format like this - {4A5325A6-1B14-471E-91A9-C93722A690E9}. Then we encrypt user's host IP address using XOR algorithm:

strAccess = FncCreateNewAccessId (strUserId, objConn)
strHostIPEncrypted = EnDeCryptXOR(strAccess, strHostIP)

And using for encryption password new Access Code, we can be sure that at any given time moment no more then one user can use same credentials simultaneously - Access Code is unique for every user's login.

Then we call procedure called SendFormHTML(ByVal AccessCode) which gets for argument our newly created Access Code, creates HTML form with Access Code in hidden form variable, and automatically submit our new form to Main.asp page.

In Main.asp page we get again current calling host IP address using:

strHostIP = Request.ServerVariables("REMOTE_HOST")

and our Access Code in hidden form variable:

strAccessCode = request.form("txtAccessCode")

Then we call procedure CheckAccessRights with arguments Access Code and current page Host IP address, it encrypts current page Host IP address using for password Access Code, and then it checks in database and if does not exist same Access Code or saved in database host IP do not match current Host IP, it redirects user back to login.asp page:

'=================================================================
'This function checks User's Access Rights 
'-----------------------------------------------------------------
Sub CheckAccessRights(ByVal AccessCode, ByVal HostIP)
Dim objConn, rsAccessCode
Dim strHostIPEncrypted, strHostIPEncryptedFromDB
HostIP = Trim(CStr(HostIP))
HostIP = Replace(HostIP,".","")
strHostIPEncrypted = EnDeCryptXOR(AccessCode,HostIP)
Call Database_ConnOpen(objConn, strConnect)
set rsAccessCode = FncGetAccessCode (AccessCode,objConn)
if rsAccessCode.bof and rsAccessCode.eof then   'no data!
    Response.Redirect "login.asp?msg=1"
else
    strHostIPEncryptedFromDB = rsAccessCode("USER_HOST_IP")
    If strHostIPEncryptedFromDB = strHostIPEncrypted Then
         ' do nothing user has valid access
    Else ' back to login
        Response.Redirect "login.asp?msg=1"
    End If
end if
Call ADODB_CleanObject(rsAccessCode)
Call ADODB_CleanObject(objConn)
End Sub
'=================================================================

If check is successful we call modMainHTML procedure with argument Access Code and again the same way we create HTML form with Access Code in hidden form variable, but this time we do not submit it programmatically - lets users do some work instead ;-)

I think you get the idea now - just pass on from page to page our Access Code in hidden form variable and check it with CheckAccessRights procedure to be sure that Dr. Evil do not try to fool you. Beware from the Dark Side and may the force be with you!

Happy Programming!
Valko

Download

For brevity and simplicity the rest of the code is not listed here. All the code, including the SQL scripts, can be found in the following zip file: LoginAuthXOR.zip (6 KB).

Links


Home |  News |  Samples |  Articles |  Lessons |  Resources |  Forum |  Links |  Search |  Feedback

Internet.com
The Network for Technology Professionals

Search:

About Internet.com

Legal Notices, Licensing, Permissions, Privacy Policy.
Advertise | Newsletters | E-mail Offers