Chris Tankersley

  • Home
  • About
  • Portfolio
  • Projects
Twitter RSS
Category Archives: Uncategorized

Getting Started with Reflection

Posted on September 3, 2010 by Chris
2 Comments

Reflection is a metaprogramming construct that allows a program to look into itself and do a multitude of different things – gain meaning, watch execution, call code, or even provide feedback. In PHP this sort of thing is more oriented to frameworks, but the power of reflection can be harnessed to do a lot of different things.

With PHP 5, PHP gained a robust reflection class that allows a developer to gain access to just about every aspect of an object and interact with it. The key is figuring out what is available, and then exploiting it to gain additional benefits.

Part of PhpORM, an object-relational-mapper project that I’ve been working on, that I’ve wanted to do is make it easy to create databases based on PHP objects without a lot of overhead. Doctrine does this well in 1.2 (which is really the only version I’ve used) by allowing a developer to generate schemas from yaml files and compile them into PHP objects. One thing I don’t like about Doctrine is that it gets kind of confusing pretty quickly and was a major turn off for me the first few times I tried to use it. I also like to keep as much in my PHP code as I can.

One feature of PhpORM is the SQL generation comments (which is somewhat of a misnomer – they are used right now for SQL generation, but will be expanded into more). Let’s set up a basic entity so that we have something to work with:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Person {
    /**
     * For the sake of demonstration, we're setting this private
     */
    private $_allowDynamicAttributes = false;
 
    /** type=primary_autoincrement */
    protected $id = 0;
    /** type=varchar length=255 null */
    protected $name;
    /** type=text null */
    protected $biography;
}

The ReflectionClass

One of the main components in reflection programming in PHP is the ReflectionClass. This core class allows a developer to starting digging through an object and pulling out information. What kind of information? Here’s a small taste:

  • Constants
  • Property Names
  • Method Names
  • Static properties
  • Namespace
  • If the Class is abstract or final

That’s just a small sampling.

Getting Started

So how do we start reflecting on a class to get this information? Just pass it the name of a class:

1
$class = new ReflectionClass('Person');

Really, that’s all there is too it. The $class object has now associated itself with a specific class (in this case our Person class) and we can start inquiring on it.

Getting Properties

Let’s find out what properties are in our class and print them out. To do this, we just call getProperties(), which returns an array of ReflectionProperty objects:

1
2
3
4
5
6
7
8
9
$properties = $class->getProperties();
foreach($properties as $property) {
    echo $property->getName()."\n";
}
// Output:
// _allowDynamicAttributes
// id
// name
// biography

By default the ReflectionClass will return all of the members of a class, not just public ones. You can alter this by passing a parameter to getProperties(). Valid parameter values are ReflectionProperty::IS_STATIC, ReflectionProperty::IS_PUBLIC, ReflectionProperty::IS_PROTECTED, and ReflectionProperty::IS_PRIVATE.

1
$private_properties = $class->getProperties(ReflectionProperty::IS_PRIVATE);

Working with Properties

Now that we have a list of properties, we can start to get more information about them instead of the class as a whole. As we can see above, we can get the name of a property via getName(). We can also get the DocBlock comments, the status of a property, and get or set values on objects. Since we’re looking to get information about the properties in Person, and that metadata is stored in the DocBlock, let’s extract that information.

1
2
3
4
5
6
7
8
9
10
11
foreach($properties as $property) {
    if($property->isProtected()) {
        $docblock = $property->getDocComment();
        preg_match('/ type\=([a-z_]*) /', $property->getDocComment(), $matches);
        echo $matches[1]."\n";
    }
}
// Output:
// primary_autoincrement
// varchar
// text

Since the _allowDynamicAttributes is private, it was skipped (not that it would have matched the regex anyway).

Getting Methods

Getting Methods and working with them is just like with Properties. You can use getMethods() to get an array of ReflectionMethod objects, and from those get their names, comments, prototypes, statuses, etc.

Let’s say that we had put getters (getId(), getName(), getBio()) and setters (setId(), setName(), setBio()) on our entity class. We want to set each property and retrieve it. If the setter or getter doesn’t exist, throw an exception.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$data = array('id' => 1, 'name' => 'Chris', 'bio' => 'I am am a PHP developer');
foreach($data as $key => $value) {
    if(!$class->hasProperty($key)) {
        throw new Exception($key.' is not a valid property');
    }
 
    if(!$class->hasMethod('get'.ucfirst($key))) {
        throw new Exception($key.' is missing a getter');
    }
 
    if(!$class->hasMethod('set'.ucfirst($key))) {
        throw new Exception($key.' is missing a setter');
    }
 
    // Make a new object to interact with
    $object = new Person();
 
    // Get the getter method and invoke it with the value in our data array
    $setter = $class->getMethod('set'.ucfirst($key));
    $setter->invoke($object, $value);
 
    // Get the setter method and invoke it
    $setter = $class->getMethod('get'.ucfirst($key));
    $objValue = $setter->invoke($object);
 
    // Now compare
    if($value != $objValue) {
        echo 'Getter or Setter has modified the data.';
    } else {
        echo 'Getter and Setter does not modify the data.';
}

Depending on what exactly happens with the getter and setter methods will determine the comparison result. If we’re missing any getters and setters, this test will alert us and we can fix it.

Start Reflecting On Your Code

See what I did there? Yeah, I’m sorry too. Anyway, hopefully this sheds a bit of light on the Reflection powers that are inherent in PHP. You can reflect on more than just Classes. There are reflection bits for functions, extensions, objects, even parameters. Once you get a grasp on reflection and what it can do, you gain just that extra bit of power of your code.

If you want to see reflection in action, take a look at PhpORM_Cli_GenerateSql. It uses reflection to build a CREATE TABLE statement based upon an entity, all using reflection.

Categories: Uncategorized

I Moved!

Posted on May 29, 2010 by Chris
No Comments

Well, the website moved anyway. The website is now hosted through Applied Innovations, a wonderful and professional hosting company that I had the chance to use during php|architect’s Great PHP on Windows contest.

Here’s to a great relationship and time with them!

Categories: Uncategorized

Hashing Is Not Encryption

Posted on October 14, 2009 by Chris
3 Comments

One of my pet peeves when talking with other programmers is when they use the wrong terminology. One of the most common ones that comes up for me is the issue of Encryption, and most of the time people are not encrypting, but hashing. And yes, there is a distinction.

What Hashing Is

Hashing is a mechanism for figuring out if two things are similar and is a one-way process. You take an object (file, string of text, ISO) and convert it to a fixed length string. You can then use this key to see if something else is the same thing.

The most common example of this is with large downloads. All the major Linux distributions will give an MD5 hash for their downloads so that you can verify that the file was not corrupted during transmission. You can run the ISO file through an MD5 generator which will give you back a 32 character string. If that string matches what Canonical says was their MD5, you have a match and your ISO is good.

In programming, one of the most common methods for hashing is password. In this case it is done for two reasons:

  1. You never, ever store passwords in Plaintext in a database
  2. You never should care what the user’s password is

Since #2 means you never need to know what the hash stands for, Hashing is a light-weight alternative to encryption while still providing security.

$password = md5($_POST['password']);
$username = $_POST['username'];
$result = mysql_query("SELECT username, password FROM user_accounts WHERE password = '$password' AND username = '$username'");
if( mysql_num_rows($result) == 1 ) {
echo 'Found a proper account!';
} else {
echo 'Invalid username and Password';
}

Salts

No, not Bacon Salt. Salts are additional bits of text you add to something before hashing to prevent someone from cracking the hashes that you are using.

$salt = 'ThisIsAReallyLongAndSecureString';
$hash = md5($_POST['password'] . $salt);
echo md5($_POST['password']) . ' != ' . $hash;

Salts are only useful if you are trying to use Hashing for security reasons, like storing passwords. If you are looking for just verification then a salt is useless. If you are using hashing for security purposes, ALWAYS USE A SALT.

Proper Hashing

Prior to PHP 5.1.2, the two most common ways to hash a file was to use either of the built-in hashing functions for MD5 or SHA1. Due to the fact that MD5 and SHA1 are considered insecure I don’t recommend using them even with a salt. You can generate a hash very easily using either MD5 or SHA1 and it should work on every single platform.

$sha1 = sha1('This is a string');
$md5 = md5('This is a string');

Since 5.1.2 PHP has added a proper hashing library that allows you to take advantage of more powerful algorithms. It is turned on by default, but if PHP is compiled by hand it can be disabled.

You can find out what algorithms are installed on a system by running the hash_algos() function. This returns an array of different algorithms that are installed on the system and that are available for use. These are also the names that can be used with the companion function hash(). So, if you wanted to store a password in the database the proper way using a hash, you would do something like the following:

// Our Salt
$salt = 'SuperSecretSaltNoOneWillEverFindOutAbout';
// The user-supplied, unhashed password and username
$usPassword = $_POST['password'];
$sUsername = mysql_real_escape_string($_POST['username']);
// Generate a SHA-384 hash using our salt
$sPassword = hash('sha384', $usPassword . $salt);
// Save it to the DB
mysql_query("UPDATE user_accounts SET password = '$sPassword' WHERE username = '$sUsername'");

Fine, what is Encryption then?

If Hashing is a one-way street, Encryption is two-way. You would use encryption whenever you need to safely store information but need to retrieve it later. (Again, you almost never need to know what a user’s password is, so why use encryption?) Encryption is also a heavier action than hashing.

Say we had a table, user_accounts, which had the following fields:

  • id
  • username
  • password
  • name
  • social_security_number
  • address_street
  • address_city
  • address_state
  • address_zip
  • cc_number
  • cc_type
  • cc_cvv
  • cc_exp_date

We would want to hash the password obviously. ID, username, and name we can probably not worry about doing anything too. Everything else though we would want to encrypt as all that information can be used in a very destructive manner if the database is stolen, but we need to use that data. Encryption would allow us to store that information in the database and sleep at night, yet still pull it back up when we needed it.

Keys

Keys, unlike Salts in hashes, are required. The key is used during the encryption process as a constant. If you use the wrong key you will not get back what you stored as the key is actually used for both encryption and decryption. Like a Salt, you’ll want to store this somewhere such as a file with limited read access.

For security reasons you will also want to look at a key rotation plan. One advantage that hashing has over encryption is that it is not meant to turn the random output of the hash back into something useful, where encryption is designed for just that purpose. If someone gets a hold of the encryption key, it is trivial to decrypt the data.

You will want to consider a key rotation plan because of this. Every set number of days you will want to decrypt all the data using the old key and re-encrypt it with the new key. Yes, it is time consuming, but that is the tradeoff for using encryption and staying secure.

Encryption Made Easy

PHP can do encryption as well as hashing. I personally prefer using the Mcrypt library that is available on most Linux systems, but PHP can also use OpenSSL. Encryption is a fairly heavy weight process and requires a bit of setup to get going. I’ve created a simple class for setting up and using Mcrypt at http://code.google.com/p/tws-code/ .

$key = 'SuperSecretKey';
$twsMcrypt = new Tws_Mcrypt($key);
$encryptedString = $twsMcrypt->encrypt('This is a secret message');
$unencryptedString = $twsMcrypt->decrypt($encryptedString');

Tws_Mcrypt can also take a second constructor argument to specify the type of encryption to use, otherwise it defaults to RIJNDAEL_128. It also encodes the encrypted string in Base64 to make storage easier, so if you encrypt something using Tws_Mcrypt and try to decrypt it straight, make sure you Base64 decode it first.

“Unless you are a cryptanalyst, don’t do your own crypto”

One final comment on hashing and encryption. The algorithms that are used in either case are tried and tested algorithms that are hard to crack and, in some cases, extremely sophisticated. People much, much smarter have taken the time to develop them and you, me, nor anyone that is not a cryptanalyst will do better.

Don’t think that the nifty encryption algorithm you came up with last night while you were in the zone will be any better than the ones that ship in PHP or in libraries like Mcrypt or OpenSSL. It won’t be and will only put you at risk.

So which to use?

Use Hashing when:

  • You don’t care what the actual data is
  • You just need to do verification
  • You need something extremely light-weight

Use Encryption when:

  • Data needs to be secured, but pulled back up later

Keep all this in mind next time you are talking to someone about how your application works. Don’t tell them you are encrypting passwords in the database when what you are really doing is hashing them. Don’t think that using straight MD5 is a viable means for data security.

Hopefully this will help you choose which type of security based on what you are doing as well.

Categories: Programming, Tutorials, TWS Software, Uncategorized | Tags: crypto, hashing, PHP

Shell Scripting: Part 2

Posted on June 2, 2007 by Chris
No Comments

Today brought more advanced shell scripting as I wrangled with administering users on the new site. This brought me in contact with learning Sed and Awk, as well as some more complicated bash tutorials.

So far I’m finding shell scripting an easy, yet powerful, mechanism for automating web site administration. I’m currently writing a mini-tutorial on what I’m setting up, in case anyone else is interested in creating a development system for web design on their own server.

Sed and Awk Micro-Primer – http://www.faqs.org/docs/abs/HTML/sedawk.html

Advanced Bash-Scripting Guide – http://tldp.org/LDP/abs/html/

Categories: Programming, Servers, Uncategorized | Tags: Bash, Command Line, Shell Scripts
  • Search

  • Archives

    • February 2012
    • January 2012
    • September 2011
    • August 2011
    • April 2011
    • December 2010
    • November 2010
    • September 2010
    • August 2010
    • May 2010
    • April 2010
    • February 2010
    • January 2010
    • November 2009
    • October 2009
    • September 2009
    • June 2009
    • May 2009
    • February 2009
    • January 2009
    • November 2008
    • October 2008
    • July 2008
    • May 2008
    • February 2008
    • December 2007
    • October 2007
    • August 2007
    • July 2007
    • June 2007
    • May 2007
  • Categories

    • Code Releases
    • Doing Development
    • Hardware
    • IBM i
    • JavaScript
    • Joomla!
    • MySQL
    • Non-Programming
    • Operating Systems
    • Personal
    • PHP
    • Programming
    • Project Management
    • Reviews
    • Servers
    • Software
    • This Site
    • Tutorials
    • TWS Software
    • Uncategorized
    • ZendCon 2010
© Chris Tankersley. Proudly Powered by WordPress | Nest Theme by YChong