Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: Secure Login System

  1. #1

    Secure Login System

    Am developing a secure login system for a web interface to a sensitive area of our company.

    I wanted to do something a little bit different than using the normal login method

    client sends password as clear text --> server hashes password and compare against stored hash

    so I came up with a way to salt the password, hash it and then send the hash so the password is hashed before being sent so even if it is intercepted during transmission only the hash is captured which is useless as the random string which is hashed with the password changes each session.

    This has 2 advantages

    1. As mentioned above it stops the capturing of the password during transmission
    2. If logging in from an internet cafe or similar there is no chance of the browser storing the password as it will store the hash.

    The way it works is as so :

    1. User enters password
    2. Password is hashed
    3. Random key is added to password hash
    4. Combined key and hashed password is rehashed and sent to server

    the random key that is used to salt the password is passed in the session

    when the hash is received by the server it takes the normal password hash adds the key from the session to it hashes the combination and compares it to the one received from the form.

    The reason I hash the password twice (once on its own and once when it has been salted) is due to the fact that the password will be stored in the DB as a hash.

    Anyways on with the code :
    (btw in these examples the username/password is hard coded but in final example this will be checked against the database)

    Page with form
    Code:
    <?php
    
    $default_username = "admin";
    $default_password = md5(test);
    
    session_start();
    if($_SESSION['key'] == "")
    	{
    	$random_string = ((date("dmyHi") + rand(0, 3000)) * 5);
    	$_SESSION['key'] = $random_string;
    	}
    
    ?>
    
    <!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>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>Secure Login System</title>
    <style type="text/css">
    <!--
    body,td,th {
    	font-family: Arial, Helvetica, sans-serif;
    	font-size: 10px;
    	color: #999999;
    }
    body {
    	background-color: #333333;
    }
    .container {
    	background: #333333;
    	padding: 10px;
    	width: 250px;
    	border: thin solid #999999;
    	margin: auto;
    }
    input {
    	font: 10px Arial, Helvetica, sans-serif;
    	color: #999999;
    	border: thin solid #999999;
    	background-color: #333333;
    }
    a:link {
    	color: #999999;
    }
    a:visited {
    	color: #999999;
    }
    a:hover {
    	color: #999999;
    }
    a:active {
    	color: #999999;
    }
    -->
    </style>
    <script language="JavaScript" src="md5.js"></script>
    </head>
    
    <body>
    <div class="container">
    
    <?php
    	//read cookie
    	$cvalue = $_COOKIE["secure_login"];
    	//get username and password from cookie
    	list($c_name, $c_pass) = split(":", $cvalue);
    	
    	$full_pass = md5($_SESSION['key'].$default_password);
    	
    	if($full_pass == $c_pass && $c_name == $default_username)
    		{
    		echo "You are logged in<br />";
    		echo "<a href=\"logout.php\">Logout?</a>";
    		}
    	else
    		{?>
    	<form id="form1" name="form1" method="post" action="login.php">
    		<table width="100%" border="0" cellspacing="3">
    			<tr>
    				<td width="31%">Username : </td>
    				<td width="69%"><input name="username" type="text" id="username" /></td>
    			</tr>
    			<tr>
    				<td>Password : </td>
    				<td><input name="password" type="text" id="password" /></td>
    			</tr>
    			<tr>
    				<td></td>
    				<td><input type="submit" name="Submit" value="Login" <?php echo 'onclick="password.value = calcMD5(\''.$random_string.'\' + calcMD5(password.value))"'; ?> /></td>
    			</tr>
    		</table>
    	</form>
    	<?php } ?>
    </div>
    </body>
    </html>
    login script
    Code:
    <?php
    
    session_start();
    $username = $_POST['username'];
    $password = $_POST['password'];
    
    $default_username = "admin";
    $default_password = md5(test);
    
    $full_pass = md5($_SESSION['key'].$default_password);
    
    if($full_pass == $password && $username == $default_username)
    	{
    	setcookie( "secure_login", "$username:$password" );
    	get_url("index.php");
    	}
    else
    	{
    	die("Error With Login");
    	}
    
    function get_url($url)
    {
    	header("Location: $url");
    	
    	echo "<html>\n<head>\n";
    	echo "<meta http-equiv=\"refresh\" content=\"2;url=$url/\">\n";
    	echo "</meta></head>\n<body>\n";
    	  
    	
    	echo "You will be redirected to the site - if you are not click <a href=\"$url\">here</a>\n";
    	echo "<script LANGUAGE=\"JavaScript\">\n";
    	echo "window.location=\"$url\";";
    	echo "</script>";
    	echo "\n";
    	echo "</body>\n</html>";
    	
    }
    
    ?>
    logout page (with thanks to php.net)
    Code:
    <?php
    // Initialize the session.
    // If you are using session_name("something"), don't forget it now!
    session_start();
    
    // Unset all of the session variables.
    $_SESSION = array();
    
    // If it's desired to kill the session, also delete the session cookie.
    // Note: This will destroy the session, and not just the session data!
    if (isset($_COOKIE[session_name()])) {
       setcookie(session_name(), '', time()-42000, '/');
    }
    
    // Finally, destroy the session.
    session_destroy(); 
    
    setcookie ("secure_login", "", time()-99999);
    
    get_url("index.php");
    
    
    function get_url($url)
    {
    	header("Location: $url");
    	
    	echo "<html>\n<head>\n";
    	echo "<meta http-equiv=\"refresh\" content=\"2;url=$url/\">\n";
    	echo "</meta></head>\n<body>\n";
    	  
    	
    	echo "You will be redirected to the site - if you are not click <a href=\"$url\">here</a>\n";
    	echo "<script LANGUAGE=\"JavaScript\">\n";
    	echo "window.location=\"$url\";";
    	echo "</script>";
    	echo "\n";
    	echo "</body>\n</html>";
    	
    }
    
    ?>
    I also used the Javascript md5 script by Greg Holt [ http://pajhome.org.uk ]
    Code:
    /*
     * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
     * Digest Algorithm, as defined in RFC 1321.
     * Copyright (C) Paul Johnston 1999 - 2000.
     * Updated by Greg Holt 2000 - 2001.
     * See http://pajhome.org.uk/site/legal.html for details.
     */
    
    /*
     * Convert a 32-bit number to a hex string with ls-byte first
     */
    var hex_chr = "0123456789abcdef";
    function rhex(num)
    {
      str = "";
      for(j = 0; j <= 3; j++)
        str += hex_chr.charAt((num >> (j * 8 + 4)) & 0x0F) +
               hex_chr.charAt((num >> (j * 8)) & 0x0F);
      return str;
    }
    
    /*
     * Convert a string to a sequence of 16-word blocks, stored as an array.
     * Append padding bits and the length, as described in the MD5 standard.
     */
    function str2blks_MD5(str)
    {
      nblk = ((str.length + 8) >> 6) + 1;
      blks = new Array(nblk * 16);
      for(i = 0; i < nblk * 16; i++) blks[i] = 0;
      for(i = 0; i < str.length; i++)
        blks[i >> 2] |= str.charCodeAt(i) << ((i % 4) * 8);
      blks[i >> 2] |= 0x80 << ((i % 4) * 8);
      blks[nblk * 16 - 2] = str.length * 8;
      return blks;
    }
    
    /*
     * Add integers, wrapping at 2^32. This uses 16-bit operations internally 
     * to work around bugs in some JS interpreters.
     */
    function add(x, y)
    {
      var lsw = (x & 0xFFFF) + (y & 0xFFFF);
      var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
      return (msw << 16) | (lsw & 0xFFFF);
    }
    
    /*
     * Bitwise rotate a 32-bit number to the left
     */
    function rol(num, cnt)
    {
      return (num << cnt) | (num >>> (32 - cnt));
    }
    
    /*
     * These functions implement the basic operation for each round of the
     * algorithm.
     */
    function cmn(q, a, b, x, s, t)
    {
      return add(rol(add(add(a, q), add(x, t)), s), b);
    }
    function ff(a, b, c, d, x, s, t)
    {
      return cmn((b & c) | ((~b) & d), a, b, x, s, t);
    }
    function gg(a, b, c, d, x, s, t)
    {
      return cmn((b & d) | (c & (~d)), a, b, x, s, t);
    }
    function hh(a, b, c, d, x, s, t)
    {
      return cmn(b ^ c ^ d, a, b, x, s, t);
    }
    function ii(a, b, c, d, x, s, t)
    {
      return cmn(c ^ (b | (~d)), a, b, x, s, t);
    }
    
    /*
     * Take a string and return the hex representation of its MD5.
     */
    function calcMD5(str)
    {
      x = str2blks_MD5(str);
      a =  1732584193;
      b = -271733879;
      c = -1732584194;
      d =  271733878;
    
      for(i = 0; i < x.length; i += 16)
      {
        olda = a;
        oldb = b;
        oldc = c;
        oldd = d;
    
        a = ff(a, b, c, d, x[i+ 0], 7 , -680876936);
        d = ff(d, a, b, c, x[i+ 1], 12, -389564586);
        c = ff(c, d, a, b, x[i+ 2], 17,  606105819);
        b = ff(b, c, d, a, x[i+ 3], 22, -1044525330);
        a = ff(a, b, c, d, x[i+ 4], 7 , -176418897);
        d = ff(d, a, b, c, x[i+ 5], 12,  1200080426);
        c = ff(c, d, a, b, x[i+ 6], 17, -1473231341);
        b = ff(b, c, d, a, x[i+ 7], 22, -45705983);
        a = ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
        d = ff(d, a, b, c, x[i+ 9], 12, -1958414417);
        c = ff(c, d, a, b, x[i+10], 17, -42063);
        b = ff(b, c, d, a, x[i+11], 22, -1990404162);
        a = ff(a, b, c, d, x[i+12], 7 ,  1804603682);
        d = ff(d, a, b, c, x[i+13], 12, -40341101);
        c = ff(c, d, a, b, x[i+14], 17, -1502002290);
        b = ff(b, c, d, a, x[i+15], 22,  1236535329);    
    
        a = gg(a, b, c, d, x[i+ 1], 5 , -165796510);
        d = gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
        c = gg(c, d, a, b, x[i+11], 14,  643717713);
        b = gg(b, c, d, a, x[i+ 0], 20, -373897302);
        a = gg(a, b, c, d, x[i+ 5], 5 , -701558691);
        d = gg(d, a, b, c, x[i+10], 9 ,  38016083);
        c = gg(c, d, a, b, x[i+15], 14, -660478335);
        b = gg(b, c, d, a, x[i+ 4], 20, -405537848);
        a = gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
        d = gg(d, a, b, c, x[i+14], 9 , -1019803690);
        c = gg(c, d, a, b, x[i+ 3], 14, -187363961);
        b = gg(b, c, d, a, x[i+ 8], 20,  1163531501);
        a = gg(a, b, c, d, x[i+13], 5 , -1444681467);
        d = gg(d, a, b, c, x[i+ 2], 9 , -51403784);
        c = gg(c, d, a, b, x[i+ 7], 14,  1735328473);
        b = gg(b, c, d, a, x[i+12], 20, -1926607734);
        
        a = hh(a, b, c, d, x[i+ 5], 4 , -378558);
        d = hh(d, a, b, c, x[i+ 8], 11, -2022574463);
        c = hh(c, d, a, b, x[i+11], 16,  1839030562);
        b = hh(b, c, d, a, x[i+14], 23, -35309556);
        a = hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
        d = hh(d, a, b, c, x[i+ 4], 11,  1272893353);
        c = hh(c, d, a, b, x[i+ 7], 16, -155497632);
        b = hh(b, c, d, a, x[i+10], 23, -1094730640);
        a = hh(a, b, c, d, x[i+13], 4 ,  681279174);
        d = hh(d, a, b, c, x[i+ 0], 11, -358537222);
        c = hh(c, d, a, b, x[i+ 3], 16, -722521979);
        b = hh(b, c, d, a, x[i+ 6], 23,  76029189);
        a = hh(a, b, c, d, x[i+ 9], 4 , -640364487);
        d = hh(d, a, b, c, x[i+12], 11, -421815835);
        c = hh(c, d, a, b, x[i+15], 16,  530742520);
        b = hh(b, c, d, a, x[i+ 2], 23, -995338651);
    
        a = ii(a, b, c, d, x[i+ 0], 6 , -198630844);
        d = ii(d, a, b, c, x[i+ 7], 10,  1126891415);
        c = ii(c, d, a, b, x[i+14], 15, -1416354905);
        b = ii(b, c, d, a, x[i+ 5], 21, -57434055);
        a = ii(a, b, c, d, x[i+12], 6 ,  1700485571);
        d = ii(d, a, b, c, x[i+ 3], 10, -1894986606);
        c = ii(c, d, a, b, x[i+10], 15, -1051523);
        b = ii(b, c, d, a, x[i+ 1], 21, -2054922799);
        a = ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
        d = ii(d, a, b, c, x[i+15], 10, -30611744);
        c = ii(c, d, a, b, x[i+ 6], 15, -1560198380);
        b = ii(b, c, d, a, x[i+13], 21,  1309151649);
        a = ii(a, b, c, d, x[i+ 4], 6 , -145523070);
        d = ii(d, a, b, c, x[i+11], 10, -1120210379);
        c = ii(c, d, a, b, x[i+ 2], 15,  718787259);
        b = ii(b, c, d, a, x[i+ 9], 21, -343485551);
    
        a = add(a, olda);
        b = add(b, oldb);
        c = add(c, oldc);
        d = add(d, oldd);
      }
      return rhex(a) + rhex(b) + rhex(c) + rhex(d);
    }
    comments?

    //next steps is to add in number of login attempts etc - but this is just the basic login system with the salt

  2. #2
    whoops just noticed that if you enter an incorrect password $_SESSION['key'] still remains which means that each subsequent attempt fails

    so changed (login.php)

    Code:
    else
    	{
    	die("Error With Login");
    	}
    to

    Code:
    else
    	{
    	$_SESSION = array();
    	die("Error With Login");
    	}
    this simply clears all session information (inc key) on a failed attempt so a new key is generated for each attempt.

  3. #3
    Member
    Join Date
    Aug 2002
    Location
    San Antonio, Texas
    Posts
    49
    WoW, good eye valhallen..... I felt like I needed dramamine after looking at that!
    \"They have the internet on computers now?\"

  4. #4
    Junior Member
    Join Date
    Jan 2006
    Posts
    24
    A few weeks ago I wrote my first servlet that contained a primitive login system. The system simply took the password field, sent it across the network, and compared it to an encrypted file stored on the server. (This is obviously insecure...)

    I see that the code you have written is more interesting. It provides greater security since the password is encrypted before it is sent over. However, I was wondering: does this script protect the user from a keylogger? I am thinking that the answer is no.

    What needs to be done in order to prevent key logging? Is this even possible?

  5. #5
    Just Another Geek
    Join Date
    Jul 2002
    Location
    Rotterdam, Netherlands
    Posts
    3,401
    Originally posted here by stonee
    However, I was wondering: does this script protect the user from a keylogger? I am thinking that the answer is no.
    You're correct..
    What needs to be done in order to prevent key logging? Is this even possible?
    Should be obvious: Prevent the installation of a keylogger..
    Oliver's Law:
    Experience is something you don't get until just after you need it.

  6. #6
    Senior Member
    Join Date
    Jul 2004
    Posts
    548
    stonee - May I also point out that this thread is flashing so you should have started a new thread for your question.

    Cheers,

    -jk

  7. #7
    Senior Member Spekter1080's Avatar
    Join Date
    Oct 2005
    Location
    Iowa
    Posts
    101
    wow! I am just starting out in the security field, and this code just blows me out of the water! The best that I've been able to come up with so far is a client-side fixed password script (made from javascript). Nice job!
    there's always a way in...

  8. #8
    Senior Member
    Join Date
    Jul 2004
    Posts
    548
    If you want to thank valhallen then you can always contact him via PM or give him antipoints. This thread is old, hence the flashing dates of the top posts. Please do not revive old threads...

  9. #9
    Junior Member
    Join Date
    Mar 2006
    Posts
    1
    Good jop man

    we will wiat you to make fourm

  10. #10
    Originally posted here by stonee
    A few weeks ago I wrote my first servlet that contained a primitive login system. The system simply took the password field, sent it across the network, and compared it to an encrypted file stored on the server. (This is obviously insecure...)

    I see that the code you have written is more interesting. It provides greater security since the password is encrypted before it is sent over. However, I was wondering: does this script protect the user from a keylogger? I am thinking that the answer is no.

    What needs to be done in order to prevent key logging? Is this even possible?
    yes it is e.g. creating an optional on-line keybord on the authenication page!
    user will type the password by clicking his mouse on the keybord! - that minimizes the chances of your input being hooked!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •