Archive

Posts Tagged ‘assistance’

It’s Here: PHP + Password + Salt Tutorial

April 5th, 2009 admin 20 comments

Well, I’ve finally gotten to it! Here’s that long promised tutorial for you guys! I hope it helps. I won’t do a lot of explaining in the post seeing as most of it I think I made pretty clear in the code itself but I’ll explain the function of each document :)

I’ve also prepare the whole tutorial in a convenient download link for those who wish to just download it. This may be the most efficient way to look at the code until I fix the wordpress theme to actually include a worthwhile PHP code in post function XD. This looks ugly no doubt. So you can download that at:
PHP Password+Salt Encryption Tutorial – Files Download (Also will be provided at the end of the post!)

First, here’s the config.php. This basically starts our session (so users can log in – it’s the first file included in the operative page: only index so it carries over. Would also need to be the first file included in all other documents unless they begin with “session_start();” as well).

<?php
// Start our sessions
session_start();

// Just some definitions of DB info
define("DATABASE","YOUR_TABLE");
define("DBUSER","YOUR_USERNAME");
define("DBPASS","YOUR_PASSWORD");
define("DBHOST","localhost");

// Script security
define("IS_SCRIPT",true);

?> 

Next, we have our index.php. No true functionality in this script, it’s basically just a simple file to make all the functions work.

<?php
/**
 * Salt Encryption Tutorial by Dennis McWherter
 *
 * (C) 2009 Dennis McWherter. All Rights Reserved.
 *
 * This is where all of our functions are. Yes a lot of these
 * Some of this stuff is extra nonsense, but makes life a lot
 * more difficult for hackers.
 *
 */
require_once("config.php");
require_once("functions.php");$login = new Login;if(!isset($_GET['page'])){
  $_GET['page'] = "index";
}switch($_GET['page']){
  default:
    if(!$_SESSION['username']){      print "<form name="login" method="post" action="?page=login">
    <p>User: <input type="text" name="user" /></p>
    <p>Pass: <input type="password" name="pass" /></p>
    <p><input type="submit" value="login" /></p>
    <p>Register</p></form>";
      exit;
    } else {      print "Hello ".$_SESSION['username'].",<br /><br />Welcome to a random test site!
    <br /><br />Your password is safe here ;) <br /><br />logout";
      exit;
    }
  break;
  case 'register':
    if(!isset($_POST['user']) OR !isset($_POST['pass'])){
      print "<p>All fields are required! (If they are not filled out, you will be
    returned to this page!)</p><br /><br />    <form name="reg" method="post" action="?page=register">
    <p>User: <input type=text" name="user" /></p>
    <p>Pass: <input type="password" name="pass" /></p>
    <p><input type="submit" value="register" /></p>
    </form>";
      exit;    } else {
      if(!$login->register($_POST['user'],$_POST['pass'])){
        print "Login failed: Username already in use!";
        exit;
      } else {
        print "Login successful! You can now login!";        exit;
      }
    }
  break;
  case 'login':
    if(!isset($_POST['user']) OR !isset($_POST['pass'])){
      $_GET['page'] = "index";
    } else {      $login->login($_POST['user'],$_POST['pass']);
    }
  break;
  case 'logout':
    if(!isset($_SESSION['username'])){
      print "User is not logged in!";
    } else {      if(session_destroy()){
        print "User logged out successfully!";
      } else {
        print "User could not be logged out!";
      }
    }
  break;}

?> 

Now, here’s the extensive script which does it all! It is more or less thoroughly documented, so no worries there. Should be pretty well explained. Here goes:

<?php
/**
 * Salt Encryption Tutorial by Dennis McWherter
 *
 * (C) 2009 Dennis McWherter. All Rights Reserved.
 *
 * This is where all of our functions are. Yes a lot of these
 * Some of this stuff is extra nonsense, but makes life a lot
 * more difficult for hackers.
 *
 */
// Script security :)
if(!defined("IS_SCRIPT")){
  print "Unauthorized access";
  exit;
}class Login
{  /**
   * Constructor :D
   *
   */
  function __construct(){
    mysql_connect(DBHOST,DBUSER,DBPASS);
    mysql_select_db(DATABASE);
  }  /**
   * Register function :D
   *
   */
  function register($user,$pass){
    // Simple checks.. umm. Yeah let's make sure user doesn't exist XD
    $check = mysql_query("SELECT * FROM users WHERE user='".mysql_escape_string($user)."'");
    if(mysql_num_rows($check) != 0){
      return false;
    }    // Let's begin with making our first and second salt character set
      // This is our first set of possible salt characters. Shuffle so always different all aspects
    $set1 = str_shuffle("!@#$%^&*()_+=-';:,<.>126AaBbJjKkLlSdDsQwWeErqRtTyY");
      // Second set. Same thing, different characters though :D
    $set2 = str_shuffle("1234567890`~ZxzxCcVvBb?[]{}pP");    // Now the loops to actually make the salt characters
    // We'll be using the rand(); function give us random chars from the shuffled sets
    // The for loops are fairly simple.
    // Salt1 = 12 char
    // Salt2 = 10 char
    for($i=0;$i<12;$i++){
      $salt1 .= $set1[rand() % strlen($set1)-.04];
    }    for($i=0;$i<10;$i++){
      $salt2 .= $set2[rand() % strlen($set2)-.07];
    }    // Now let's generate a pattern. We'll have only about 4 combinations.
    // For time sake we'll only do a few simple ones.
    $part[1] = "{salt1}";
    $part[2] = "{salt2}";
    $part[3] = "{pass}";
    $psort   = array_rand($part,3);
    $pattern = $part[$psort[0]].".".$part[$psort[1]].".".$part[$psort[2]];    // Now for pass
    $grep = array("/{salt1}/","/{salt2}/","/{pass}/"); // Identify pattern
    $repl = array($salt1,$salt2,$pass); // Make pattern real    // Now replace the pattern with actual values XD
    $sendpass = preg_replace($grep,$repl,$pattern);    // Send all to DB
    $query = "INSERT INTO users (`id`,`user`,`password`,`salt1`,`salt2`,`pattern`) VALUES
    (NULL, '".mysql_escape_string($user)."',
    '".md5($sendpass)."', '".mysql_escape_string($salt1)."',
    '".mysql_escape_string($salt2)."', '".mysql_escape_string($pattern)."')";
    if(!mysql_query($query)){      print "DB Connection failed: ".mysql_error();
      return false;
    }
    return true;
  }  /**
   * Login Function
   *
   */
  function login($user,$pass){
    // Grab info by username since usernames are unique anyway...
    $query = "SELECT * FROM users WHERE user='".mysql_escape_string($user)."' LIMIT 1;";
    if(!mysql_query($query)){      print "DB Connection Failed: ".mysql_error();
      return false;
    }
    $info  = mysql_fetch_assoc(mysql_query($query));
    // Use the grep and replace arrays again to replace information from pattern!
    $grep = array("/{salt1}/","/{salt2}/","/{pass}/"); // Identify pattern
    $repl = array($info['salt1'],$info['salt2'],$pass); // Make pattern real    $pwd  = preg_replace($grep,$repl,$info['pattern']); // Generate password how it should be.    // Now let's make sure the user is properly identifying!
    if(md5($pwd) != $info['password']){
      print "Incorrect password!";
      unset($info);
      return false;
    }    // All checks out... Let's create session data and give a success msg.. We're just about done
    // anyway ;)     $_SESSION['username'] = $user;
    print "You've logged in successfully! Please return home";    // Delete all info in the $info var
    unset($info);
    return true;
  }
}
?> 

Oh yeah, and can’t forget the database structure! Run this query to duplicate the database :)

CREATE TABLE `users` (
`id` BIGINT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`user` VARCHAR( 32 ) NOT NULL ,
`password` VARCHAR( 32 ) NOT NULL ,
`salt1` VARCHAR( 12 ) NOT NULL ,
`salt2` VARCHAR( 10 ) NOT NULL ,
`pattern` VARCHAR( 22 ) NOT NULL
) ENGINE = MYISAM ;

Regards,
Dennis M.

Again, that download link is: PHP Password+Salt Encryption Tutorial – Files Download