####About
This script serves as proof of concept that bcrypt()
is much better at keeping passwords safe than regular one-way encryption algorythms because adjustable work factors limit the number of attempts per second or minute that a hash can be checked.
####Warning
Do not under any circumstances use this script, or any variation in production. It is only meant to be a proof of concept.
##Phalcon
Phalcon is a super fast PHP web framework implemented as a C extension.
Because the attached script deals with routes Phalcon needs to be run a special way. The command used is: php -S localhost:80 ~/.htrouter.php
. You must ensure that you put the correct path for the .htrouter.php
file so Phalcon can interpret paths correctly
##Classes
There is only one class in this proof, which is the Bcrypt
class created by Christian Metz.
##Functions
There are five functions to the Bcrypt
class: hashPassword($password, $workFactor)
, checkPassword($password, $storedHash)
, _genSalt($workFactor)
, _getRandomBytes()
, _validateIdentifier($hash)
.
- hashPassword
- Creates the hashed password of
$password
using a work factor of$workFactor
- Creates the hashed password of
- checkPassword
- Checks previously hashed password of
$password
against the stored hash of$storedHash
- Checks previously hashed password of
- _genSalt
- Uses
substr()
,strtr()
,base64_encode()
, and_getRandomBytes()
to generate our 22 character random salt
- Uses
- _getRandomBytes
- Used with
_genSalt
andopenssl_random_pseudo_bytes()
to generate our very secure random salt
- Used with
- _validateIdentifier
- Used to ensure that the hash being generated or checked conforms to
bcrypt()
encryption standards; valid identifiers are:['2a', '2x', '2y']
- Used to ensure that the hash being generated or checked conforms to
##Routes
Along with two functions there are two routes to be used. /hash/
and /verify/
. Use /hash/{password}
to generate the hash of a given password and /verify/{password}/{hash}
to verify the given hash. As you may or may not have noticed the bcrypt()
algorythm ensures that the hash id different for each generation (even of the same password) which is not true for the majority of other encryptions. However, all generated hashes will still verify correctly! Therein lies the power of bcrypt()
.
##Other
This script is not meant to be viewed in the browser because of the characters available to a bcrypt()
hash. It is meant to be used with curl
via the command line.
C:\>curl localhost/hash/TestPassword
$2y$10$HlByIUUXw6b6FPPUfdZalOZU2ezNwPNWp2BO9VgSD7MFDRPWBGAIO
C:\>curl localhost/verify/TestPassword/$2y$10$HlByIUUXw6b6FPPUfdZalOZU2ezNwPNWp2BO9VgSD7MFDRPWBGAIO
Password is Valid!
C:\>
##Problems with Crypto Hashes
Some of the more daunting issues with other crypto algorithms are things such as brute force attacks, and hash collision attacks. Brute force attacks take advantage of one way encryption algorithms by hashing every known combination of words and dumping them into a database to be referenced later; milw0rm and similar services come to mind. Hash collision attacks make use of the inherent mathematic failure with most cryptographic algorithms such as md5
, sha1
, sha256
, sha512
, and sha-3
in which input strings can be of infinite length but the resulting cryptographic hash is limited to a certain length. This means that innevitably at some point even if inputs are totally differet a hacker will be able to recreate the sum of a hash using a totally different input string which will identify as a correct hash.
##Where it Succeeds
The strength of bcrypt()
comes from a very unlikely place. It's speed. By speed I mean it's very slow to calculate hashes. Not slow in the sense that it's so slow you wouldn't want to use it, however, the speed of cryptographic hash creation can easily influence the type of attack that a hacker would want to execute on a hash or group of hashes. Especially if it takes much longer to calculate resulting hashes for a brute for attack making it basically impractical to execute that type of attack. To that reguard, key stretching as it's called, becomes a strength by making someone think twice about taking many weeks or months to crack a single hash, and not many hours or just a few days.