Scripts

Goed beveiligd inlogsysteem met classen

Een login script dat aardig beveiligd is. Op php hulp heb ik niet van deze beveiligen kunnen vinden bij de scripts, dus ik dacht laat ik die er dan zelf maar opzetten. Het password wordt gehashed verzonden ( SHA256 ) dus vrijwel onmogelijk om te achterhalen. Verder wordt bruteforcen tegen gegaan d.m.v. een tijdelijk ban system na een x aantal verkeerde inlog pogingen. En last but not least is het script ook beveiligd tegen session hijacking d.m.v. het bijhouden van ips. Al deze functies in een aantal classen gegoten, en voila hier staat ie. Het is geen volledig werkend member systeem, maar wel makkelijk uit te breiden. De sessies worden in een database bijgehouden. NB: test.login moet je invullen naar eigen wensen Veel plezier ermee. Download links: Hier Hier (Mirror)

goed-beveiligd-inlogsysteem-met-classen
[b]class.clsUser.php:[/b]

<?php
	
	// Constante definities, spreken voor zich
	define('LOGIN_SESSION_EXPIRED',1);
	define('LOGIN_NO_USER',2);
	define('LOGIN_INCORRECT_PWD',4);
	define('LOGIN_SECURITY_BAN',8);
	define('LOGIN_SUCCESS',16);
	
	define('REGISTER_INVALID_USERNAME',1);
	define('REGISTER_USER_EXISTS',2);
	define('REGISTER_INVALID_EMAIL',4);
	define('REGISTER_EMAIL_EXISTS',8);
	define('REGISTER_SUCCESS',16);
	
	class clsUser  { 
		
		private $state_loaded; // true als clsUser::load() is aangeroepen
		
		private $id;
		private $username;
		private $startdate;
		private $email;
		
		private $db;
		
		public function __construct(){
			$this->db = clsDatabase::getInstance('test.login'); // Laad de database met de gegevens uit 'test.login'
			$this->state_loaded = false;
		}
		
		public function __destruct(){
		}
		
		public function get_logged_in() { 
			/* pre:  -
			   post: Geeft terug of de gebruiker is ingelogd, kijkt ook of sessie niet gestolen is.
			*/
			
			if ( isset ( $_SESSION['ip']) ) {
				return (( $_SESSION['ip'] == $_SERVER['REMOTE_ADDR'] ) && (isset($_SESSION['id'])));
				
			} else {
				$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
				return isset($_SESSION['id']);
				
			}
		}
		
		public function get_id() { return $this->id; }
		public function get_username() { return $this->username; }
		public function get_startdate() { return $this->startdate; }
		
		public function get_banned() {
			/* pre:  -
			   post: Returned true of false. True als persoon gebanned is, false als dit niet het geval is.
			   	     Init $_SESSION['bf_security_timer'] als dit nodig is, en unset deze ook als het nodig is.
			*/
			
			if ( $this->get_bf_counter() >= 3 ) {
			
				if ( isset ( $_SESSION['bf_security_timer'] ) ) {
					
					if ( $_SESSION['bf_security_timer'] + 5 * 60 <= time() ) {
						unset ( $_SESSION['bf_security_timer'] );
						set_bf_counter(1,false);
						return false;
					}
					
				} else {
					$_SESSION['bf_security_timer'] = time();
					
				}
			
			} else {
				return false;
			
			}
			
			return true;
		
		}
		
		public function get_bf_counter() { 
			/* pre:  -
			   post: Return hoeveel pogingen er zijn gedaan om in te loggen. 
			    	 Init $_SESSION['bf_security_counter'] als dit nodig is.
			*/
			
			if ( isset ( $_SESSION['bf_security_counter'] ) ) {
				return $_SESSION['bf_security_counter']; 
				
			} else { 
				$_SESSION['bf_security_counter'] = 1;
				return 1;
				
			}
		}
		
		public function set_bf_counter( $arg_plus = 1, $arg_relative = true) {
			/* pre:  0 < $arg_plus < MAX_INT, (bool) $arg_relative
			   post: Update $_SESSION['bf_security_counter'] met $arg_plus
			*/ 
			 
			if ( $arg_relative ) {
				$_SESSION['bf_security_counter'] += $arg_plus ;
				
			} else {
				$_SESSION['bf_security_counter'] = $arg_plus ;
				
			}
		}
		
		public function set_username( $arg_username ) {
			/* pre:  -
			   post: $this->username geset als $arg_username alleen letters of underscore bevat en 2 < len($arg_username) <= 12 
			*/ 
			
			if ( (preg_match('/[A-Z_]+/i',$arg_username)) && (strlen($arg_username) > 2) && (strlen($arg_username) <= 12) ) {
				$this->username = $arg_username;
			}
		}
		
		public function set_email ( $arg_email ) {
			/* pre:  -
			   post: $this->email geset als $arg_email valide is 
			*/ 
			if ( preg_match('/\b[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i',$arg_email) ) {
				$this->email = $arg_email;
			}
		}
		
		public function log_in( $arg_username, $arg_response ) {
			/* pre:  -
			   post: geeft een waarde terug of de login succesvol is. Alleen succesvol bij LOGIN_SUCCESS 
			*/ 
			
			if ( $this->get_banned() ) {
				return LOGIN_SECURITY_BAN;
			}
			
			// Bepaal of de sessie nog niet verlopen is
			if ( isset ( $_SESSION['challenge'] ) ) {
				$rs_user = $this->db->query("SELECT * FROM users WHERE username = '" . $this->db->quote_smart($arg_username) . "'"); 
				
				// Bepaal of user bestaat
				if  ( $rs_user->CountRows() ) {
					$arr_user = $rs_user->fetchRow();
					
					// Password was gehashed verzonden, dus ook nu hashen om te vergelijken
					$f = bin2hex(mhash(MHASH_SHA256, $arg_username . '()' . $_SESSION['challenge'] ) );
					$f = $arr_user['password'] . $f;
					$f = bin2hex(mhash(MHASH_SHA256,$f));
					
					// Vergelijk server met client waarde
					if ( $f ==  $arg_response ) {
						$_SESSION['id'] = $arr_user['id'];
						
						$this->logged_in = true;
						$this->id = $arr_user['id'];
						$this->username = $arr_user['username'];
						$this->startdate = $arr_user['startdate'];
						$this->email = $arr_user['email'];
						
						// De challenge hebben we niet meer nodig
						unset($_SESSION['challenge']);
						
						return LOGIN_SUCCESS;
						
					} else {
						$this->set_bf_counter();
						return LOGIN_INCORRECT_PWD;
					
					}
				
				} else {
					return LOGIN_NO_USER;
				
				}
					
			} else {
				return LOGIN_SESSION_EXPIRED;
			
			}
		
		}
		
		public function log_off () {
			/* pre:  -
			   post: Gebruiker is uitgelogd
			*/ 
			
			if ( $this->get_logged_in() ) {
				unset($_SESSION['id']);
				
			}
		}
		
		public function load(){
			/* pre:  -
			   post: Laad de huidige instantie van het user object 
			*/ 
			
			if  (! $this->state_loaded && $this->get_logged_in() ) {
				$this->state_loaded = true;
				
				$arr_user = $this->db->query("SELECT * FROM users WHERE id = " . $this->db->quote_smart($_SESSION['id']) )->fetchRow(); 
				
				$this->id = $arr_user['id'];
				$this->username = $arr_user['username'];
				$this->startdate = $arr_user['startdate'];
				$this->email = $arr_user['email'];
			
			}
		}
		
		public function register_user (  ) {
			/* pre:  -
			   post: Gebruiker toevoegd in database, en e-mail met wachtwoord verzonden
			*/ 
			
			// Niks doen als het object geladen is
			if ( ! $this->state_loaded ) { 
				
				// Username en email moeten valide zijn
				if ( ($this->username != '') && ($this->email != '') ) {
					
					$rs_u = $this->db->query("SELECT username FROM users WHERE username = '" . $this->db->quote_smart($this->username) . "' OR email = '" . $this->db->quote_smart($this->email) . "'");
					
					// Gebruiker nog emailaddress mag bestaan
					if  ($rs_u->CountRows() ) {
						$arr_u = $rs_u->fetchRow();
						
						// We weten dat of er iemand met deze username of iemand met dit emailadres bestaat, maar we weten nog niet welke van de twee.
						if ( $arr_u['username'] == $this->username ) {
							return REGISTER_USER_EXISTS;
						
						} else {
							return REGISTER_EMAIL_EXISTS;
						
						}
						
					} else {
						$pwd = '';
						
						// Maak een nieuw wachtwoord van alleen maar hoofdletters
						for ( $i = 1; $i < 9;$i++ ){
							$pwd .= chr(rand(65,90));
						}
						
						// Voet gebruiker in in de database
						$rs_u = $this->db->query("INSERT INTO users VALUES(NULL,'{$this->username}','" . bin2hex(mhash(MHASH_SHA256,$pwd)) . "',NOW(), '{$this->email}')");
							
						$this->id = $rs_u->getInsertId();
						$this->startdate = time();
						
						// Header maken voor het verzenden van e-mail
						$header  = "Content-type: text/html; charset=iso-8859-1\r\n";
						$header .= "Return-Path: [email protected]\r\n";
						$header .= "X-Sender: [email protected]\r\n";
						$header .= "From: Login Test <[email protected]>\r\n";
						$header .= "X-Mailer:PHP 5.1\r\n";
						$header .= "MIME-Version: 1.0\r\n"; 
						
						mail($this->email, "Login account", $pwd,$header);
						
						return REGISTER_SUCCESS;							
					}	
						
				} else {
					if ( $this->username == '' ) {
						return REGISTER_INVALID_USERNAME;
					}else{
						return REGISTER_INVALID_EMAIL;
					}
				}
			}
			
		}
		
	}
	
?>

[b]class.clsDatabase.php:[/b]
<?php
	
	class clsDatabase { 
		
		protected $con_id;
		protected $host;
		protected $user;
		protected $password;
		protected $database;
		
		private $query_counter;
		
		public function __construct( $arg_param ) {
			
			// Laad de connectie gegevens uit een array
			if ( is_array ($arg_param) && count($arg_param) == 4 ) {
				foreach ( $arg_param as $parameter => $value ) {
					$this->{$parameter} = $value;
				}
			
			// Laad de connectie gegevens uit een bestand
			// !! LET OP: niet veilig, gebruiker kan dit bestand ook zien. Beveilingen met .htaccess of andere aanpak bedenken
			} elseif ( is_file ( $arg_param ) ) {
				if (! $handle = file ( $arg_param ) ) {
					trigger_error('Invalid path parameter given for connection');
					
				} else {
					foreach ($handle as $line) {
						$arr = explode('=',$line);
						$this->$arr[0] = trim($arr[1]);
						
					}
					
				}
			
			} else {
				trigger_error('No connection parameters provided',E_USER_ERROR);
			
			}
			
			// Maak de connectie naar de database
			$this->connect();
			
			// Er zijn nog geen queries uitgeoverd
			$query_counter = 0;
		
		}
		
		public function __destruct() {
		}
		
		public static function getInstance( $arg_param ) {
			/* pre:  -
			   post: Geeft instantie van huidig object, altijd maar 1 instantie te gelijk ( SINGLETON )
			*/
			static $instance;
            
			if( ! isset( $instance ) ){
                $object= __CLASS__;
                $instance = new $object($arg_param);
            }
			
            return $instance;
		}
		
		public function get_con_id() { return $this->con_id; }
		public function get_host() { return $this->host; }
		public function get_user() { return $this->user; }
		public function get_password() { return $this->password; }
		public function get_database() { return $this->database; }
		
                public function get_query_counter() { return $this->query_counter; }

		private function connect() {
			/* pre:  -
			   post: Huidige connectie wordt gesloten en nieuwe connectie is aangamaakt
			*/
			
			// Sluit huidige connectie als die er is.
			if ( $this->con_id ) {
				mysql_close($this->con_id);
				$this->con_id = NULL;
			}
			
			// Alles moet wel zijn ingevuld
			if ( ($this->host == '') || ($this->user == '') || ($this->password == '') || ($this->database == '') ){
				
				trigger_error('Insufficient connection parameters given',E_USER_ERROR);
				
			} else {
				if ( ! $this->con_id = mysql_connect($this->host,$this->user,$this->password ) ) {
					trigger_error('Unable to create connection',E_USER_ERROR);
					
				} else {
					if ( ! mysql_select_db($this->database,$this->con_id) ) {
						trigger_error('Error selecting database',E_USER_ERROR);
					}
				}
				
			}
			
		}
		
		public function query($arg_sql) {
			/* pre:  -
			   post: Een clsResult wordt geretured met de huidige query
			   		 Querycounter is met 1 verhoogd
			*/
			
			if ( ! $result = mysql_query($arg_sql, $this->con_id) ) {
				trigger_error('Error performing query, error given: ' .mysql_error($this->con_id) . ' on query: ' .$arg_sql,E_USER_ERROR);
			}
			
			$this->queries++;
			
			return new clsResult($this, $result);
		}
		
		public function quote_smart( $arg_value ) {
			/* pre:  -
			   post: $arg_value wordt ge-escaped. Werkt ook met magic_quotes
			*/ 
			
			if (get_magic_quotes_gpc()) {
				$arg_value = stripslashes($arg_value);
			}
			// Quote if not integer
			$arg_value = mysql_real_escape_string($arg_value, $this->con_id );
			
			return $arg_value;
		}
	
	}
	
	class clsResult {
		
		protected $myparent; // clsDatabase
		protected $result;
		
		public function __construct(clsDatabase $arg_parent, $arg_query ) {
			$this->myparent = $arg_parent;
			$this->result = $arg_query;
			
		}
		
		public function __destruct() {
			// Geef resources van query vrij, maar alleen als het een resource is
			if ( is_resource($this->result) ) {
				mysql_free_result($this->result);
			}
			
		}
		
		public function CountRows() {
			/* pre:  $this->result is resource
			   post: Het aantal rijen in result, false voor 0 rijen
			*/
			
			$rows = mysql_num_rows($this->result);
			
			if ( $rows == 0 ){
				return false;
			}
			
			return $rows;
		}
		
		function fetchRow(){
			/* pre:  $this->result is resource
			   post: Geef een array van de huidige rij 
			*/
			
			return mysql_fetch_array($this->result,MYSQL_ASSOC);
		}
		
		public function CountAffectedRows() {
			/* pre:  $this->result is GEEN resource, maar resultaat van UPDATE of INSERT
			   post: Geeft het aantal aangepaste rijen weer, false voor 0 rijen
			*/
			
			$rows = mysql_affected_rows($this->myparent->get_con_id());
			
			if ($rows == 0) { 
				return false;
				
			} else {
				return $rows;
				
			}
		}
		
		public function getInsertId() {
			/* pre:  $this->result is GEEN resource, maar resultaat van UPDATE of INSERT
			   post: Geeft het id van de laatst ingevoegde rij
			*/
			
			if( ! $id = mysql_insert_id( $this->myparent->get_con_id() ) ){
				trigger_error('Error getting ID',E_USER_ERROR);
				
			}
			
			return $id;
		}
		
		public function seekRow( $arg_row = 0 ) {
			/* pre:  $this->result is resource, 0 =< $arg_row =< count($this->result)
			   post: Zoek een rij in het resultaat
			*/
			
			if( ! mysql_data_seek($this->result,$arg_row)){
				trigger_error('Error seeking data',E_USER_ERROR);
				
			}
		}
		
	}			
	
?>

[b]class.clsSessionHandler.php:[/b]
<?php
class clsSessionHandler {
		
		protected $session_started; // Is sessie al gestart?
		protected $lifetime; 
		
		private $db;
		
		public function __construct() {
			
			// Maak een nieuwe connectie naar de database
			$this->db = clsDatabase::getInstance('test.login');
			
			// Deze classe moet sessies afhandlen, dus geef dat aan
			session_set_save_handler(array($this,'sess_open'),array($this,'sess_close'),array($this,'sess_read'),
									 array($this,'sess_write'),array($this,'sess_destroy'),array($this,'sess_gc'));
			
			session_start();
			$this->session_started = true;
			
		}
		
		public function __destruct() {
		}
		
		public static function getInstance() {
			/* pre:  -
			   post: Geeft instantie van huidig object, altijd maar 1 instantie te gelijk ( SINGLETON )
			*/
			
			static $instance;
            
			if(!isset($instance)){
                $object= __CLASS__;
                $instance = new $object;
            }
			
            return $instance;
		}
		
		public function sess_open ( $save_path, $session_name ) {
			// Bepaal de max leeftijd van een sessie
			$this->lifetime = ini_get("session.gc_maxlifetime");
			
			// Als iemand al een sessie had en deze is nog niet verlopen, geef hem dan opnieuw diezelfde sessie
			$rs = $this->db->query( "SELECT session_id FROM sessions WHERE ip = '" . $_SERVER['REMOTE_ADDR'] . "'");
			
			if ( $rs->CountRows() ) {
				$rs_arr = $rs->fetchRow();
				session_id($rs_arr['session_id']);
			}
			
			return true;
		}
		
		public function sess_close () {
			$this->sess_gc($this->lifetime);
			return true;
		}
		
		public function sess_read( $id ) {
			
			$rs = $this->db->query( "SELECT data FROM sessions WHERE session_id = '" . $this->db->quote_smart($id) . "'");
			
			if ( $rs->CountRows() ) {
				$rs_arr = $rs->fetchRow();   
				return $rs_arr['data'];
				
			} else {
			 	$rs = $this->db->query("INSERT INTO sessions  VALUES ( '', NOW(), '" .$this->db->quote_smart($id) ."', '{$_SERVER['REMOTE_ADDR']}',0)");
				return false;
			} 
		}
		
		public function sess_write ( $id, $sess_data ) {
			// Als iemand al ingelogd is haal dan het id uit de data, nodig voor users_online bijvoorbeeld
			if ( preg_match ( '/id\|s:(\d+?):\"(\d+?)\"/i',$sess_data, $matches) ) {
				$user = $matches[2];
			} else { 
				$user = 0;
			}
			
			$rs = $this->db->query("INSERT INTO sessions  VALUES ( '$sess_data', NOW(), '" . $this->db->quote_smart($id) . "', '{$_SERVER['REMOTE_ADDR']}', '$user') ON DUPLICATE KEY UPDATE data = '" .$this->db->quote_smart($sess_data) . "', user = '$user'");
			return true;
			
		}
		
		public function sess_destroy ( $id ) {
			$this->db->query("DELETE FROM sessions WHERE session_id = '" .$this->db->quote_smart($id) ."'");
			return true;
		}
		
		public function sess_gc ( $maxlifetime ) {
			// Vernietig alle sessies die verlopen zijn
			$rs = $this->db->query("DELETE FROM sessions WHERE time + $maxlifetime < NOW()");
			
			return $rs->CountAffectedRows();
		}
		
	}
	
?>

[b]Index.php:[/b]
[code]
<?php
	
	// Laad alle benodigde classen automatisch
	if ( ! function_exists('__autoload') ) {
		function __autoload( $arg_class ) {
			require_once("class.$arg_class.php");
		}
	}
	
	// We hebben sessies nodig, dus maak deze aan
	$obj_handler = clsSessionHandler::getInstance();
	
	$obj_user = new clsUser();
	
	if ( $obj_user->get_banned() ) { 
		echo "You got banned for 5 mins";
		return;
	}
	
	if ( $obj_user->get_logged_in() ) {
		$msg = "You already are logged in.";
	
	} else {
		
		if ( isset ( $_POST['username'], $_POST['response'] ) ){
			$h = $obj_user->log_in($_POST['username'], $_POST['response'] );
			
			switch ( $h ) {
				case LOGIN_SESSION_EXPIRED:
					$msg = "Session expired";
				break;
				
				case LOGIN_NO_USER:
					$msg = "No such user";
				break;
				
				case LOGIN_INCORRECT_PWD:
					$msg = "Incorrect password";
				break;
				
				case LOGIN_SUCCESS:
					$msg = "You are now logged in";
				break;
				
				case LOGIN_SECURITY_BAN:
					$msg = "You got banned for 5 mins";
					return;
				break;
			}
		}
	}
	
	// Nieuwe challenge nodig voor login
	$_SESSION['challenge'] = sha1(pack("H*", sha1(mt_rand())));
?>

<!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>Login</title>
		
		<script type="text/javascript" src="sha.js"></script>
		<script type="text/javascript" language="javascript">
			function create_response ( ) {
				var password = document.getElementById('password');
				var challenge = document.getElementById('challenge');
				var login = document.forms['login'];
				
				login.response.value = sha256_digest(sha256_digest(password.value) + sha256_digest(login.username.value + '()' + challenge.value));
				
				password.value = '';
				challenge.value = '';
				
				return true;
			}
		
		</script>
		
	</head>

	<body>
		<?php
			if ( isset ( $msg) ) {
				echo $msg;
			}
		?>
		<form method="post" name="login" action="<?php echo basename($_SERVER['PHP_SELF']);?>" onsubmit="return create_response(); ">
			<p>Username: <input type="text" name="username" /></p>
			<p>Password: <input type="password" id="password" /></p>
			<input type="hidden" id="challenge" value="<?php echo $_SESSION['challenge'];?>"/>
			<input type="hidden" name="response" />
			<input type="submit" value="Login" />
		</form>
		
		<p><a href="register.php" title="Create account">Click here for a free account</a></p>
		
	</body>
</html>

[/code]

[b]Register.php[/b]
[code]
<?php 
	
	// Laad alle benodigde classen automatisch
	if ( ! function_exists('__autoload') ) {
		function __autoload( $arg_class ) {
			require_once("class.$arg_class.php");
		}
	}
	
	// We hebben sessies nodig, dus maak deze aan
	$obj_handler = clsSessionHandler::getInstance();
	
	if (isset ($_POST['username'],$_POST['email'])) {
		$obj_user = new clsUser();
		$obj_user->set_username($_POST['username']);
		$obj_user->set_email($_POST['email']);
		$ret = $obj_user->register_user();
		
		switch ( $ret ) {
			case REGISTER_INVALID_USERNAME:
				$msg = "Invalid username";
			break;
			
			case REGISTER_INVALID_EMAIL:
				$msg = "Invalid email address";
			break;
			
			case REGISTER_USER_EXISTS:
				$msg = "User already exists";
			break;
			
			case REGISTER_EMAIL_EXISTS:
				$msg = "Email already taken.";
			break;
			
			case REGISTER_SUCCESS:
				$msg = "Account created";
				include('index.php');
				return;
			break;
		}
	}
?>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
		<title>Untitled Document</title>
	</head>

	<body>
		<?php
			if ( isset ( $msg) ) {
				echo $msg;
			}
		?>
		<form action="<?php echo basename($_SERVER['PHP_SELF']);?>" method="post">
			<p>Desired username: <input type="text" name="username" /></p>
			<p>Your emailaddress: <input type="text" name="email" /></p>
			<input type="submit" value="Register" />
		</form>
	</body>
</html>

[/code]

[b]sha.js:[/b]
[code]

/* SHA256 logical functions */
function rotateRight(n,x) {
	return ((x >>> n) | (x << (32 - n)));
}
function choice(x,y,z) {
	return ((x & y) ^ (~x & z));
}
function majority(x,y,z) {
	return ((x & y) ^ (x & z) ^ (y & z));
}
function sha256_Sigma0(x) {
	return (rotateRight(2, x) ^ rotateRight(13, x) ^ rotateRight(22, x));
}
function sha256_Sigma1(x) {
	return (rotateRight(6, x) ^ rotateRight(11, x) ^ rotateRight(25, x));
}
function sha256_sigma0(x) {
	return (rotateRight(7, x) ^ rotateRight(18, x) ^ (x >>> 3));
}
function sha256_sigma1(x) {
	return (rotateRight(17, x) ^ rotateRight(19, x) ^ (x >>> 10));
}
function sha256_expand(W, j) {
	return (W[j&0x0f] += sha256_sigma1(W[(j+14)&0x0f]) + W[(j+9)&0x0f] + 
sha256_sigma0(W[(j+1)&0x0f]));
}

/* Hash constant words K: */
var K256 = new Array(
	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
);

/* global arrays */
var ihash, count, buffer;
var sha256_hex_digits = "0123456789abcdef";

/* Add 32-bit integers with 16-bit operations (bug in some JS-interpreters: 
overflow) */
function safe_add(x, y)
{
	var lsw = (x & 0xffff) + (y & 0xffff);
	var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
	return (msw << 16) | (lsw & 0xffff);
}

/* Initialise the SHA256 computation */
function sha256_init() {
	ihash = new Array(8);
	count = new Array(2);
	buffer = new Array(64);
	count[0] = count[1] = 0;
	ihash[0] = 0x6a09e667;
	ihash[1] = 0xbb67ae85;
	ihash[2] = 0x3c6ef372;
	ihash[3] = 0xa54ff53a;
	ihash[4] = 0x510e527f;
	ihash[5] = 0x9b05688c;
	ihash[6] = 0x1f83d9ab;
	ihash[7] = 0x5be0cd19;
}

/* Transform a 512-bit message block */
function sha256_transform() {
	var a, b, c, d, e, f, g, h, T1, T2;
	var W = new Array(16);

	/* Initialize registers with the previous intermediate value */
	a = ihash[0];
	b = ihash[1];
	c = ihash[2];
	d = ihash[3];
	e = ihash[4];
	f = ihash[5];
	g = ihash[6];
	h = ihash[7];

        /* make 32-bit words */
	for(var i=0; i<16; i++)
		W[i] = ((buffer[(i<<2)+3]) | (buffer[(i<<2)+2] << 8) | (buffer[(i<<2)+1] 
<< 16) | (buffer[i<<2] << 24));

        for(var j=0; j<64; j++) {
		T1 = h + sha256_Sigma1(e) + choice(e, f, g) + K256[j];
		if(j < 16) T1 += W[j];
		else T1 += sha256_expand(W, j);
		T2 = sha256_Sigma0(a) + majority(a, b, c);
		h = g;
		g = f;
		f = e;
		e = safe_add(d, T1);
		d = c;
		c = b;
		b = a;
		a = safe_add(T1, T2);
        }

	/* Compute the current intermediate hash value */
	ihash[0] += a;
	ihash[1] += b;
	ihash[2] += c;
	ihash[3] += d;
	ihash[4] += e;
	ihash[5] += f;
	ihash[6] += g;
	ihash[7] += h;
}

/* Read the next chunk of data and update the SHA256 computation */
function sha256_update(data, inputLen) {
	var i, index, curpos = 0;
	/* Compute number of bytes mod 64 */
	index = ((count[0] >> 3) & 0x3f);
        var remainder = (inputLen & 0x3f);

	/* Update number of bits */
	if ((count[0] += (inputLen << 3)) < (inputLen << 3)) count[1]++;
	count[1] += (inputLen >> 29);

	/* Transform as many times as possible */
	for(i=0; i+63<inputLen; i+=64) {
                for(var j=index; j<64; j++)
			buffer[j] = data.charCodeAt(curpos++);
		sha256_transform();
		index = 0;
	}

	/* Buffer remaining input */
	for(var j=0; j<remainder; j++)
		buffer[j] = data.charCodeAt(curpos++);
}

/* Finish the computation by operations such as padding */
function sha256_final() {
	var index = ((count[0] >> 3) & 0x3f);
        buffer[index++] = 0x80;
        if(index <= 56) {
		for(var i=index; i<56; i++)
			buffer[i] = 0;
        } else {
		for(var i=index; i<64; i++)
			buffer[i] = 0;
                sha256_transform();
                for(var i=0; i<56; i++)
			buffer[i] = 0;
	}
        buffer[56] = (count[1] >>> 24) & 0xff;
        buffer[57] = (count[1] >>> 16) & 0xff;
        buffer[58] = (count[1] >>> 8) & 0xff;
        buffer[59] = count[1] & 0xff;
        buffer[60] = (count[0] >>> 24) & 0xff;
        buffer[61] = (count[0] >>> 16) & 0xff;
        buffer[62] = (count[0] >>> 8) & 0xff;
        buffer[63] = count[0] & 0xff;
        sha256_transform();
}

/* Split the internal hash values into an array of bytes */
function sha256_encode_bytes() {
        var j=0;
        var output = new Array(32);
	for(var i=0; i<8; i++) {
		output[j++] = ((ihash[i] >>> 24) & 0xff);
		output[j++] = ((ihash[i] >>> 16) & 0xff);
		output[j++] = ((ihash[i] >>> 8) & 0xff);
		output[j++] = (ihash[i] & 0xff);
	}
	return output;
}

/* Get the internal hash as a hex string */
function sha256_encode_hex() {
	var output = new String();
	for(var i=0; i<8; i++) {
		for(var j=28; j>=0; j-=4)
			output += sha256_hex_digits.charAt((ihash[i] >>> j) & 0x0f);
	}
	return output;
}

/* Main function: returns a hex string representing the SHA256 value of the 
given data */
function sha256_digest(data) {
	sha256_init();
	sha256_update(data, data.length);
	sha256_final();
        return sha256_encode_hex();
}

/* test if the JS-interpreter is working properly */
function sha256_self_test()
{
	return sha256_digest("message digest") == 
"f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650";
}
[/code]

[b]test.login[/b]
[code]
host=localhost
user=
password=
database=
[/code]

[b]Database:[/b]
[code]
DROP TABLE IF EXISTS `sessions`;
CREATE TABLE `sessions` (
  `data` varchar(500) NOT NULL,
  `time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  `session_id` varchar(255) NOT NULL,
  `ip` varchar(12) NOT NULL,
  `user` mediumint(8) unsigned NOT NULL,
  PRIMARY KEY  (`session_id`),
  KEY `user` (`user`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
[/code]

[code]
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
  `id` mediumint(8) unsigned NOT NULL auto_increment,
  `username` varchar(30) NOT NULL,
  `password` varchar(255) NOT NULL,
  `startdate` timestamp NOT NULL default CURRENT_TIMESTAMP,
  `email` varchar(255) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='InnoDB free: 8192 kB';
[/code]

Reacties

0
Nog geen reacties.