Posts Tagged ‘PHP’

Constant time string comparison

Friday, October 22nd, 2010

I recently spotted @fabpot‘s tweet about his Symfony2 commit to prevent timing attacks. It’s a pretty simple change. Basically it just makes every password string comparison run through every character no matter if the match fails on any character. I don’t use bitwise operators much so it took a sec to spot how it works.

The comparison code is:

$result = 0;
for ($i = 0; $i < strlen($password1); $i++) {
  $result |= ord($password1[$i]) ^ ord($password2[$i]);
}
return 0 === $result;

The key components are:

ord()  // translate a character into it's ASCII value (an 8 bit integer)
^       // bitwise xor
|=     // short for left assign value bitwise or'd with new value

Just for clarity, bitwise xor evaluates to 1 for 1/0 or 0/1 or 0/0 but evaluates to 0 for 1/1. So when comparing two integers by xor'ing the bits a perfect match will evaluate to 0. Anything but an exact match will evaluate to 1.

01110000 xor
01110000
00000000  // match

01110011 xor
01110010
00000011  // nope

This means that if we xor each integer value of each character and or the produced values together it will evaluate to 0 when the two strings match. And this is always accomplished in string length time.

00000000  or
00000000  or
...
00000000
00000000  // match

As an aside, bitwise operators can do some neat stuff. This one is a solution that my Pascal instructor in college mentioned as a fast cheap way to swap screen buffers. In this example we're just swapping variable values without an intermediate.

$a = 'a';
$b = 'b';

$a ^= $b;
$b ^= $a;
$a ^= $b;

echo $a;  // b
echo $b;  // a

PHP cast as array

Tuesday, July 27th, 2010

PHP is full of shenanigans.  If you know them you can code more efficiently.  If you don’t it can make for a mess.  One of the lesser used, but useful tricks is casting as array.

If you’re not familiar with casting, check the docs:  http://php.net/manual/en/language.types.type-juggling.php

Here’s a quick breakdown of what happens when you cast to array:

php > var_dump((array)false);
array(1) {
  [0]=>
  bool(false)
}
php > var_dump((array)null);
array(0) {
}
php > var_dump((array)0);
array(1) {
  [0]=>
  int(0)
}
php > var_dump((array)"");
array(1) {
  [0]=>
  string(0) ""
}
php > var_dump((array)array());
array(0) {
}
php > var_dump((array)new StdClass);
array(0) {
}
php > class TestIterator implements IteratorAggregate {
php >   public function getIterator() {
php >     return new ArrayIterator(array(1,2,3));
php >   }
php > }
php > $a = new TestIterator;
php > var_dump((array)$a);
array(0) {
}
php > foreach ($a as $num) { echo $num,"\n"; }
1
2
3

The interesting bits here are that null, empty array and empty object all cast to empty array. Even an Iterator. Since the Iterator object is empty is casts to an empty array, even though iterating through it will produce 3 elements. Any other value casts to an array with a single element that is the value.

There’s a couple use cases I’d like to highlight from this list. Flexibility in signature params, and easier iteration:

function string_replace($string,$elements) {
  foreach((array)$elements as $element) {
    $pos = strpos($string,'?');
    if ($pos !== false) {
      $string = substr_replace($string,$element,$pos,1);
    }
  }
  return $string;
}

This is just a simple function for replacing question marks in a string with supplied string(s). By casting $elements as an array we can take a single param or an array of params without checking for it in our code. We can also passively return the string untouched if null params are supplied.

php > echo string_replace('the name is ?','jason');
the name is jason
php > echo string_replace('? ? ? at swingers',array('in','the','evening'));
in the evening at swingers