1

I've tried using sha but its not working maybe I've done something wrong.

In the database password field I have varchar(65)

If I type that long "65" it works I can login but the normal password is not hashing.

   <?php
require_once '../../../common/server/php/settings.php';



//Connect to users database
$db = mysql_connect('localhost','root','test') or die(mysql_error());
mysql_select_db('test',$db) or die(mysql_error());

//Init request parameters
$userName = (isset($_REQUEST["user_name"])) ? urldecode($_REQUEST["user_name"]) : "";
$password = (isset($_REQUEST["password"])) ? urldecode($_REQUEST["password"]) : "";
$uid = (isset($_REQUEST["uid"])) ? urldecode($_REQUEST["uid"]) : "";
$password = sha1($password);

//Check if user filled login and password in the login screen (Chat authorization)
if($userName != "" && $password != "")
{
  $sql = "SELECT * FROM users WHERE username='".$userName."' AND password='".$password."'";
}
//session/cookie base authorization (Auto login)
else if ($_SESSION['user_id']!="")
{
  $sql = "SELECT * FROM users WHERE id='".$_SESSION["user_id"]."'";
}
// Non session/cookie based autologin authorization
else if ($uid!="")
{
  $sql = "SELECT * FROM users WHERE id='".$_GET['uid']."'";
}
else
{
  echo '<auth error="AUTH_ERROR" />';
  exit;
}

//Select user data
$result = mysql_query($sql,$db);

if(mysql_num_rows($result)==1)
{
  //User found. get user info
  $usersInfo = mysql_fetch_array($result);

  $photo = FLASHCOMS_HTTP_ROOT.'common/images/User1_120.png';
  $photoModeImage = FLASHCOMS_HTTP_ROOT.'common/images/User1_40.png';   

  $answer = '<auth>';
  $answer .= '<userName><![CDATA['.$userName.']]></userName>';
  $answer .= '<gender>male</gender>';
  $answer .= '<age>'.$userInfo['age'].'</age>';
  $answer .= '<level>regular</level>';
  $answer .= '<photo><![CDATA['.$photo.']]></photo>';
  $answer .= '<photoModeImage><![CDATA['.$photoModeImage.']]></photoModeImage>';
  $answer .= '</auth>';
  echo $answer;
  exit;
}
else 
{
  //User not found OR authorization failed
  echo '<auth error="AUTH_ERROR" />';
  exit;
}

?>

the function on login script

function generateHash($plainText, $salt = null)
    {
        if ($salt === null)
        {
            $salt = substr(md5(uniqid(rand(), true)), 0, 25);
        }
        else
        {
            $salt = substr($salt, 0, 25);
        }

        return $salt . sha1($salt . $plainText);
    }

I forgot to tell that I have login script already what I am trying to do is to integrate it to my video chat.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
user1895103
  • 41
  • 1
  • 1
  • 5

4 Answers4

0

I would suggest you use Bcrypt to perfom you password hashing. I've included below a Bcrypt file i've used - may have found it on here but I can't find it to reference the post sorry!!

class Bcrypt {
  private $rounds;
  public function __construct($rounds = 12) {
    if(CRYPT_BLOWFISH != 1) {
      throw new Exception("bcrypt not supported in this installation. See http://php.net/crypt");
    }

    $this->rounds = $rounds;
  }

  public function hash($input) {
    $hash = crypt($input, $this->getSalt());

    if(strlen($hash) > 13)
      return $hash;

    return false;
  }

  public function verify($input, $existingHash) {
    $hash = crypt($input, $existingHash);

    return $hash === $existingHash;
  }

  private function getSalt() {
    $salt = sprintf('$2a$%02d$', $this->rounds);

    $bytes = $this->getRandomBytes(16);

    $salt .= $this->encodeBytes($bytes);

    return $salt;
  }

  private $randomState;
  private function getRandomBytes($count) {
    $bytes = '';

    if(function_exists('openssl_random_pseudo_bytes') &&
        (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) { // OpenSSL slow on Win
      $bytes = openssl_random_pseudo_bytes($count);
    }

    if($bytes === '' && is_readable('/dev/urandom') &&
       ($hRand = @fopen('/dev/urandom', 'rb')) !== FALSE) {
      $bytes = fread($hRand, $count);
      fclose($hRand);
    }

    if(strlen($bytes) < $count) {
      $bytes = '';

      if($this->randomState === null) {
        $this->randomState = microtime();
        if(function_exists('getmypid')) {
          $this->randomState .= getmypid();
        }
      }

      for($i = 0; $i < $count; $i += 16) {
        $this->randomState = md5(microtime() . $this->randomState);

        if (PHP_VERSION >= '5') {
          $bytes .= md5($this->randomState, true);
        } else {
          $bytes .= pack('H*', md5($this->randomState));
        }
      }

      $bytes = substr($bytes, 0, $count);
    }

    return $bytes;
  }

  private function encodeBytes($input) {
    // The following is code from the PHP Password Hashing Framework
    $itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

    $output = '';
    $i = 0;
    do {
      $c1 = ord($input[$i++]);
      $output .= $itoa64[$c1 >> 2];
      $c1 = ($c1 & 0x03) << 4;
      if ($i >= 16) {
        $output .= $itoa64[$c1];
        break;
      }

      $c2 = ord($input[$i++]);
      $c1 |= $c2 >> 4;
      $output .= $itoa64[$c1];
      $c1 = ($c2 & 0x0f) << 2;

      $c2 = ord($input[$i++]);
      $c1 |= $c2 >> 6;
      $output .= $itoa64[$c1];
      $output .= $itoa64[$c2 & 0x3f];
    } while (1);

    return $output;
  }
}

You then use this to hash your passwords:

$strength = 10;

$bcrypt = new Bcrypt($strength);
$hash = $bcrypt->hash('password'); // This will has your password

$isGood = $bcrypt->verify('password', $hash); // This will verify the password

So to complete an example for you:

$password = $_POST['password'];
$username = $_POST['username'];

if(isset($password) && islet($username)){

    $strength = 10;

    $bcrypt = new Bcrypt($strength);
    $hash = $bcrypt->hash('password'); // This will has your password

    $isGood = $bcrypt->verify('password', $hash); // This will verify the password

    if($isGood){

        $sql = "SELECT * FROM users WHERE username='".$userName."' AND password='".$password."'";

    }

}

Obviously you will need to filter your input on Username and Password to remove any SQL vulnerabilities.

ajtrichards
  • 29,723
  • 13
  • 94
  • 101
  • You should use `$2y` instead of `$2a` if possible for some reason I forget exactly. See the notes on `CRYPT_BLOWFISH` at http://php.net/crypt – Ry- May 23 '13 at 18:12
0

Can I offer an alternative for hashing the passwords? This is how I like to do it, so I hope this helps.

Add a field to your users table called password_salt. Set both your password and password_salt fields to varchar(40). When the user is created, set the salt to something unique like $salt = SHA1(microtime());. You'll use that unique salt for hashing your password. This way, every users hash is unique and can not be easily reversed with a hash lookup table.

if($userName != "" && $password != "") {
    $sql = sprintf("SELECT * FROM users WHERE username='%s' AND password=SHA1(CONCAT('%s',password_salt))"),
        mysqli_real_escape_string($userName),
        mysqli_real_escape_string($password),
    );
}

You could get a lot fancier with your salt too, like:

password=SHA1(CONCAT(user_id,'%s',password_salt,'secret code'))
jon__o
  • 1,509
  • 13
  • 14
  • thx for answer well as i said i have already login script for example i have 1 registred user and the password is e3f5cf461e471e451d81e5377b3cadcb2e6aadad12fb10d5c5c062ba116c6dc30 what i need is to tell my video chat handler to pick up that password ill update my post in i put full handler.php then you understend what im talking about – user1895103 May 23 '13 at 18:36
  • Yeah, just remember that without a per-user salt, the hashes could be vulnerable, like how LinkedIn was compromised last year. I like using MySQL for the hashing instead of some other extra library. Sorry that I don't know exactly what you are trying to accomplish, but hopefully this helps ;) – jon__o May 23 '13 at 19:09
  • @jon__o - Leaving hashing to the database is not a good idea, because they do not offer appropriate functions to hash passwords. Hash algorithms of the SHA-* family are not appropriate because they are ways too fast, instead one should use a slow key-derivation function like BCrypt or PBKDF2. – martinstoeckli May 23 '13 at 19:14
0

Use bcrypt. If someone has the user table of your database, then they can use brute force/rainbow tables/etc . Even with salt,it's just a matter of time before it can be cracked. You can now say what is point if i can use sha-1 for over 15k rounds than 1k rounds.Making many iterations with a hash function has a few subtleties, because there must be some kind of salting involved, and because existing hash functions are not as random as what could be hoped for; so care must be taken, in which case you end up with PBKDF2. bcrypt has an advantage over PBKDF2-with-SHA-1. In that bcrypt is derived from the Blowfish block cipher. If you look at the situation in details, you can actually see some points where bcrypt is better than, say, PBKDF2. Bcrypt is a password hashing function which aims at being slow. To be precise, we want the password hashing function to be as slow as possible for the attacker while not being intolerably slow for the honest systems.

SHA512 vs. Blowfish and Bcrypt

the best thing we can hope to do is to make password hashing N times slower for both the attacker and for us. we then adjust N so as not to exceed our resources.the goal is to prevent the attacker from using some non-PC hardware which would allow him to suffer less than us from the extra work implied by bcrypt.it heavily rely on access to a table which is constantly altered throughout the algorithm execution. This is very fast on a PC, much less so on a Graphics Processing Unit(where memory is shared and all the core are in complete control of the internal bus). But sometimes bcrypt is not secure, so researchers invented "scrypt". So there is a bit of controversy everywhere. the NIST people are again recomending PBKDF2. but PBKDF2 can be easily brute forced on a consumer hardware. So if you do actuall want a secure system, consult an expert and use the git and php.net manual :)

if u are looking forward to scrypt then you can use this link: https://github.com/DomBlack/php-scrypt and for bcrypt:

class SecureHash
{
public function create_hash($password, &$salt = '', $stretch_cost = 10)
{
$salt = strlen($salt) != 21 ? $this->_create_salt() : $salt;
if (function_exists('crypt') && defined('CRYPT_BLOWFISH')) {
return crypt($password, '$2a$' . $stretch_cost . '$' . $salt . '$');
}

if (!function_exists('hash') || !in_array('sha512', hash_algos())) {
throw new Exception('You must have the PHP PECL hash module installed or use PHP 5.1.2+');
}

return $this->_create_hash($password, $salt);
}


public function validate_hash($pass, $hashed_pass, $salt)
{
return $hashed_pass === $this->create_hash($pass, $salt);
}

protected function _create_salt()
{
$salt = $this->_pseudo_rand(128);
return substr(preg_replace('/[^A-Za-z0-9_]/is', '.', base64_encode($salt)), 0, 21);
}

protected function _pseudo_rand($length)
{
if (function_exists('openssl_random_pseudo_bytes')) {
$is_strong = false;
$rand = openssl_random_pseudo_bytes($length, $is_strong);
if ($is_strong === true) return $rand;
}
$rand = '';
$sha = '';
for ($i = 0; $i < $length; $i++) {
$sha = hash('sha256', $sha . mt_rand());
$chr = mt_rand(0, 62);
$rand .= chr(hexdec($sha[$chr] . $sha[$chr + 1]));
}
return $rand;
}

private function _create_hash($password, $salt)
{
$hash = '';
for ($i = 0; $i < 20000; $i++) {
$hash = hash('sha512', $hash . $salt . $password);
}
return $hash;
}

}
Community
  • 1
  • 1
argentum47
  • 2,385
  • 1
  • 18
  • 20
0

Hashing passwords with SHA-1 will not protect your passwords much more than storing them plaintext. The problem is, that the SHA-* family is designed to be fast, one can calculate about 3 Giga SHA-1 hashes per second with common hardware. So even if you already wrote a script, change it now to a better hash algorithm, it will never be so easy as now with only 1 user!

PHP 5.5 will have it's own functions password_hash() and password_verify() ready, to simplify generating BCrypt password hashes. I strongly recommend to use this excellent api, or it's compatibility pack for earlier PHP versions. The usage is very straightforward:

// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);

// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);
martinstoeckli
  • 23,430
  • 6
  • 56
  • 87