How to Store Password With PHP

There. Are. Many. People. Explaining. This.

tl;dr: store the hash (use slow hash function) with random salt, NOT the plain password, NOT the encrypted password.

This is a little class to do the hashing and verification:

<?php
// PasswordHasher.php

class PasswordHasher {
    public function hash($plain) {
        if (function_exists('password_hash')) {
            return password_hash($plain, PASSWORD_BCRYPT);
        } else {
            return crypt($plain, '$2y$10$' . substr(sha1(time()), 0, 22));
        }
    }

    public function match($plain, $hash) {
        if (function_exists('password_verify')) {
            return password_verify($plain, $hash);
        } else {
            $computed = crypt($plain, $hash);
            return $computed === $hash;
        }
    }
}

I know PHP has built-in function password_hash() and password_verify(), but just in case your PHP version is < 5.5, it provides fallback to crypt(). It uses 10 rounds (Blowfish) by default.

This is a little test script that uses that class:

<?php
// TestPasswordHasher.php
require 'PasswordHasher.php';

$password = 'I am Groot';
$hasher = new PasswordHasher();

$hash = $hasher->hash($password);
$verified = (int)$hasher->match($password, $hash);

echo "Hash: $hash\n";
echo "\n";

echo "Password: $password\n";
echo "Match with: $password\n";
echo "Is verified: $verified\n";
echo "\n";

$wrong = 'Hodor';
$verified = (int)$hasher->match($wrong, $hash);

echo "Password: $password\n";
echo "Match with: $wrong\n";
echo "Is verified: $verified\n";
echo "\n";

The output:

Hash: $2y$10$fe2a7b0a7f5c06b5b2164OYoqgU5.L6kk4Z3hxao98LV/v/cbFrMi

Password: I am Groot
Match with: I am Groot
Is verified: 1

Password: I am Groot
Match with: Hodor
Is verified: 0

Done? Well, if you think that class is a little boring, why don’t we implement it with Adapter + Factory pattern?

<?php
// PasswordAdapter.php

interface PasswordAdapter {
    public function hash($plain);
    public function match($plain, $hash);
}
<?php
// PasswordDriverCrypt.php

class PasswordDriverCrypt implements PasswordAdapter {
    public function hash($plain) {
        return crypt($plain, '$2y$07$' . substr(sha1(time()), 0, 22));
    }

    public function match($plain, $hash) {
        $computed = crypt($plain, $hash);
        return $computed === $hash;
    }
}
<?php
// PasswordDriverFunction.php

class PasswordDriverFunction implements PasswordAdapter {
    public function hash($plain) {
        return password_hash($plain, PASSWORD_BCRYPT);
    }

    public function match($plain, $hash) {
        return password_verify($plain, $hash);
    }
}
<?php
// PasswordFactory.php

class PasswordFactory {
    public static function getDriver() {
        if (function_exists('password_hash')) {
            return new PasswordDriverFunction();
        } else {
            return new PasswordDriverCrypt();
        }
    }
}

And the test script: (Make sure you have PHP >= 5.5)

<?php
// TestPasswordAdapter.php

require 'PasswordAdapter.php';
require 'PasswordDriverCrypt.php';
require 'PasswordDriverFunction.php';
require 'PasswordFactory.php';

$password = 'Dracarys!';
$driver = PasswordFactory::getDriver();
$hash = $driver->hash($password);
$verified = (int)$driver->match($password, $hash);

echo "Hash: $hash\n";
echo "\n";

echo "Password: $password\n";
echo "Match with: $password\n";
echo "Is verified: $verified\n";
echo "\n";

$wrong = 'Drakkari';
$verified = (int)$driver->match($wrong, $hash);

echo "Password: $password\n";
echo "Match with: $wrong\n";
echo "Is verified: $verified\n";
echo "\n";

$driverCrypt = new PasswordDriverCrypt();
$driverFunction = new PasswordDriverFunction();

$hash = $driverCrypt->hash($password);
$verified = (int)$driverFunction->match($password, $hash);

echo "Hashed by DriverCrypt\n";
echo "Verified by DriverFunction\n";
echo "Is verified: $verified\n";
echo "\n";

$hash = $driverFunction->hash($password);
$verified = (int)$driverCrypt->match($password, $hash);

echo "Hashed by DriverFunction\n";
echo "Verified by DriverCrypt\n";
echo "Is verified: $verified\n";
echo "\n";

Summary

Which one do you prefer? Straightforward one class or many classes with some design patterns?
I highly recommend this talk Crypto 101 by lvh.

[Rants] Emmet is Really Great for Writing XML

I’m currently dealing with Magento, and if you know anything about Magento module development, you know that it involves many XMLs. Usually writing XML is a nightmare because it’s too long, repeatedly typing “<” “>” is uncomfortable, and every tag name will be written twice. But, I found Emmet!

I use Emmet plugin with my Sublime Text. Here is a quick reference for Emmet.

Let’s say I want to write an XML like this:

<config>
  <tabs>
    <foggyline module="foggyline_happyhour">
      <label>Foggyline</label>
      <sort_order>10</sort_order>
    </foggyline>
  </tabs>

  <sections>
    <foggyline_happyhour module="foggyline_happyhour">
      <label>FoggylineHappyHour</label>
      <tab>foggyline</tab>
      <sort_order>10</sort_order>
      <show_in_default>1</show_in_default>
      <groups>
        <settings>
          <label>FoggylineHappyHour Settings</label>
          <sort_order>10</sort_order>
          <show_in_default>1</show_in_default>
          <fields>
            <custom_message>
              <label>Custom Message</label>
              <frontend_type>text</frontend_type>
              <sort_order>20</sort_order>
              <show_in_default>1</show_in_default>
            </custom_message>
          </fields>
        </settings>
      </groups>
    </foggyline_happyhour>
  </sections>
</config>

What I would do is, I scan the outermost level first.

<config>
  <tabs>
    ...
  </tabs>

  <sections>
    ...
  </sections>
</config>

Then write it as Emmet syntax. Since there will be big siblings, I enclose them using parentheses and will fill the second sibling later.

config>(tabs)+()

Now I dive into <tabs>

  <tabs>
    <foggyline module="foggyline_happyhour">
      <label>Foggyline</label>
      <sort_order>10</sort_order>
    ...

This is pretty straightforward. Note that I don’t have to read the closing tag because it will be matched automatically later.

config>(tabs>foggyline[module="foggyline_happyhour"]>label{Foggyline}+sort_order{10})+()

Now that we are finished with <tabs>, move to its sibling <sections>.

  <sections>
    <foggyline_happyhour module="foggyline_happyhour">
      <label>FoggylineHappyHour</label>
      <tab>foggyline</tab>
      <sort_order>10</sort_order>
      <show_in_default>1</show_in_default>
      <groups>
        ...

Since this is a bit long, I write that part first.

...+(sections>foggyline_happyhour[module="foggyline_happyhour"]>label{FoggylineHappyHour}+tab{foggyline}+sort_order{10}+show_in_default{1}+groups>)

Let’s descend into <groups>

      <groups>
        <settings>
          <label>FoggylineHappyHour Settings</label>
          <sort_order>10</sort_order>
          <show_in_default>1</show_in_default>
          <fields>
            ...

This is similar with before.

...+groups>settings>label{FoggylineHappyHour Settings}+sort_order{10}+show_in_default{1}+fields>)

Now we enter the last portion of the XML.

          <fields>
            <custom_message>
              <label>Custom Message</label>
              <frontend_type>text</frontend_type>
              <sort_order>20</sort_order>
              <show_in_default>1</show_in_default>
            ...

Which is just repeating the same technique.

...+fields>custom_message>label{Custom Message}+frontend_type{text}+sort_order{20}+show_in_default{1})

Now this is the full Emmet code.

config>(tabs>foggyline[module="foggyline_happyhour"]>label{Foggyline}+sort_order{10})+(sections>foggyline_happyhour[module="foggyline_happyhour"]>label{FoggylineHappyHour}+tab{foggyline}+sort_order{10}+show_in_default{1}+groups>settings>label{FoggylineHappyHour Settings}+sort_order{10}+show_in_default{1}+fields>custom_message>label{Custom Message}+frontend_type{text}+sort_order{20}+show_in_default{1})

Press TAB on that and voila. Emmet reduces the amount of characters I have to type to around 50% because I don’t have to write the closing tags and “<” “>”.

Disclaimer: [Rants] is where I talk about nonsense.

Load Local Directory with Composer

If you have been using PHP for a while, you know that Composer is the hottest PHP package manager right now. With Composer we can easily define our library requirements and it will download them.

Normally, we include libraries from Packagist, but we can also define our own repository, even a local directory! This time I’ll show you an example of how to include a local directory as library in Composer. The main idea is to use that local directory as a Git repository.

Requirements:

  • Git
  • Composer

Create Local Repository

First we create a directory that will be our local repository. Then, we put a composer.json file and the file that will our library. The structure will look like this:

/path/to/local/repository/
    composer.json
    lib/
        Caesar.php

Caesar.php is just a sample library class. The content of Caesar.php:

<?php

class Caesar {
	private $key;

	public function __construct($key) {
		$this->key = (int)$key;
	}

	public function encrypt($text) {
		return $this->slide($this->key, $text);
	}

	public function decrypt($text) {
		return $this->slide($this->key * -1, $text);
	}

	private function slide($key, $text) {
		$result = '';
		for ($i=0, $n=strlen($text); $i < $n; $i++) {
			$c = $text[$i];
			if ($this->is_alpha($c)) {
				$num = ord($c);
				$num += $key;

				if ($this->is_upper($c)) {
					if ($num > ord('Z')) {
						$num -= 26;
					} else if ($num < ord('A')) {
						$num += 26;
					}
				} else { // is_lower
					if ($num > ord('z')) {
						$num -= 26;
					} else if ($num < ord('a')) {
						$num += 26;
					}
				}
				$result .= chr($num);
			} else {
				$result .= $c;
			}
		}
		return $result;
	}

	private function is_alpha($c) {
		return ('A' <= $c && $c <= 'Z') || ('a' <= $c && $c <= 'z');
	}

	private function is_upper($c) {
		return ('A' <= $c && $c <= 'Z');
	}
}

With composer.json we tell how we structure our library source, the content of composer.json:

{
  "name": "samplelocal/caesar",
  "autoload": {
    "psr-0": {
      "Caesar": "lib/"
    }
  }
}

Now define this directory as git repository. In /path/to/local/repository/ run these commands:

composer install
git init
git add -A
git commit -m "first"

Create Application

Now we need to create a simple application that will use the library we created. Create another directory for this and make sure this new directory is not under our local repository. Create empty files so the end result will look like this:

/path/to/sample/application/
    composer.json
    encrypt.php
    decrypt.php

encrypt.php and decrypt.php are our application.

<?php
// encrypt.php
require 'vendor/autoload.php';

$cipher = new Caesar(3);
$text = implode(' ', array_slice($argv, 1));

echo $cipher->encrypt($text) . "\n";
<?php
// decrypt.php
require 'vendor/autoload.php';

$cipher = new Caesar(3);
$text = implode(' ', array_slice($argv, 1));

echo $cipher->decrypt($text) . "\n";

And for our final file, we use this composer.json to include that library in our local repository. Put this as composer.json:

{
  "name": "sampleapp/caesar",
  "repositories": [
    {
      "type": "vcs",
      "url": "/path/to/local/repository/"
    }
  ],
  "require": {
    "samplelocal/caesar": "dev-master"
  }
}

That’s how we define local repository, set type as “vcs” and url as the directory path. Since it’s considered as VCS, that’s why we set the local repository as Git repository.

This is the final setup, run composer to install our library. In /path/to/sample/application/ run this command:

composer install

If all goes well, we can test our application by running some text encryption & decryption.

php encrypt.php Lorem ipsum dolor sit amet, consectetur adipiscing elit
Oruhp lsvxp groru vlw dphw, frqvhfwhwxu dglslvflqj holw
php decrypt.php Oruhp lsvxp groru vlw dphw, frqvhfwhwxu dglslvflqj holw
Lorem ipsum dolor sit amet, consectetur adipiscing elit

Afterthought

In the future, when we update our library, we need to update the library inside the application too. We do this using composer update command.

The ability to use local directory as dependency means we can have our own private library repositories.

More information on Composer repositories.

[Rants] Opt-In, Opt-Out, and Method Overriding

Opt-in means the default state is off and you have the option to turn it on. Opt-out means the default state is on and you have the option to turn it off.

In Java, method overriding is by default enabled. If you want to disable it, you use final. In C++, method overriding is not enabled by default. If you want to use it, you use virtual.

This means in Java, method overriding is opt-out. And in C++, method overriding is opt-in.

Disclaimer: [Rants] is where I talk nonsense.

[Quick Tips] Load External JavaScript File in node-webkit

If you have been reading my posts about node-webkit, I usually write the javascript code inside index.html file. This is simply for convenience. It doesn’t mean that you can’t write your javascript code in external files like what is common with regular website.

There are two ways we can load external JS file: <script> tag and node.js require() function.

We can use <script> tag just like in regular HTML page.

<script src="multiply.regular.js"></script>
<script>
var x = new Multiply(3, 4);
console.log(x.result());
</script>

But I think for node-webkit it’s more natural to use node.js require().

<script>
var Multiply = require('./multiply.node.js');
var x = new Multiply(5, 6);
console.log(x.result());
</script>

Inside the multiply.node.js file, we set which object will be returned via magic variable module.exports.

function Multiply(a, b) {
  this.a = a;
  this.b = b;
}

Multiply.prototype.result = function () {
  return this.a * this.b;
};

module.exports = Multiply;

Note that module.exports will only exists if the script is included via require() function, if included using <script> tag, the script will produce an error because module is undefined.

If you want to know more about node.js require() function.