Skip to content

Commit babfa56

Browse files
authored
Merge pull request #18 from angryTom/feat/update-hashing
Feat/update hashing - Add password hasher
2 parents f0f3af2 + 62353d5 commit babfa56

20 files changed

+1988
-519
lines changed

.travis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
language: php
22
php:
3-
- 5.5
4-
- 5.4
5-
- 5.3
3+
- 7.1
4+
- 7.0
5+
- 5.6
66

77
# Notifications
88
notifications:

CHANGELOG.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# Changelog
2+
3+
## 2.0.0
4+
5+
### New Password Hasher
6+
7+
Version `2.0.0` comes with a new password hasher component: `AngryBytes\Hash\Hasher\Password`.
8+
This hasher is intended to be used for hashing of passwords (and other secure tokens).
9+
10+
The hasher utilises PHP's native cryptographically strong password hashing functions:
11+
`password_hash()` and `password_verify()`, see [Password Hashing](http://php.net/manual/en/book.password.php).
12+
13+
The password hasher has been setup to use PHP's default cost and algorithm.
14+
The default cost can however be overwritten by providing a cost to the the constructor, like so:
15+
16+
```php
17+
// Create a password hasher with n cost factor of 15 instead of the default (10).
18+
$passwordHasher = new \AngryBytes\Hash\Hasher\Password(15);
19+
```
20+
21+
#### Password Rehashing
22+
The password hasher offers a method to check if an existing hash needs to be **rehashed**.
23+
For example, this can be the case when the cost and/or algorithm of the password
24+
hasher has changed. If this is the case, you **should** rehash the password
25+
and update the stored hash with the rehashed value.
26+
27+
**Example**
28+
29+
In this example, we check whether an existing password is outdated and should be rehashed.
30+
31+
Note: in order to rehash the password, you will need access to its original plaintext value.
32+
Therefore, it's probably a best practice to check for and update a stale hash
33+
during login procedure, where the plaintext password is available after a login form
34+
submit.
35+
36+
```php
37+
// Create a password hasher
38+
$hasher = new \AngryBytes\Hash\Hash(
39+
new \AngryBytes\Hash\Hasher\Password
40+
);
41+
42+
// Plaintext password received via form submit.
43+
$password = '...';
44+
45+
// Persisted password hash for the User
46+
$userPasswordHash = '...';
47+
48+
// Verify the password against the hash
49+
if ($hasher->verify($password, $userPasswordHash)) {
50+
51+
// Check if the hash needs to be rehashed?
52+
if ($hasher->needsRehash($userPasswordHash)) {
53+
// Rehash password and update the user.
54+
$user->hash = $hasher->hash($password);
55+
$user->save();
56+
}
57+
}
58+
```
59+
60+
### Refactored "AngryBytes\Hash\HasherInterface"
61+
62+
Added new verification method `AngryBytes\Hash\HasherInterface::verify()` hash
63+
verification. This method accepts the following three arguments:
64+
65+
* `$data` - The data that needs to be hashed.
66+
* `$hash` - The hash that needs to match the hashed value of `$data`.
67+
* `$options` (optional) - An array with addition hasher options. What these options are depends on the active hasher.
68+
69+
### Refactored AngryBytes\Hash\Hash
70+
71+
`AngryBytes\Hash\Hash::construct()` second argument (`$salt`) has become optional
72+
to accommodate for hashers that handle their own salt, like `AngryBytes\Hash\Hasher\Password`.
73+
74+
`AngryBytes\Hash\Hash::hash()` and `AngryBytes\Hash\Hash::shortHash()` no longer accept any number of arguments but
75+
only following two:
76+
77+
* `$data` - The data that needs to be hashed. This data can be of any type, all non-scalar types will be
78+
serialized before hashing.
79+
* `$options` (optional) - An array with options that will be passed to the hasher. What these options are depends
80+
on the active hasher.
81+
82+
`AngryBytes\Hash\Hash::verify()` is a new method that's available to validate a hash in a time-safe manner.
83+
The method accepts the following arguments:
84+
85+
* `$data` - The data that needs to be hashed. This data can be of any type, all non-scalar types will be
86+
serialized before hashing.
87+
* `$hash` - The hash that needs to match the hashed value of `$data`.
88+
* `$options` (optional) - An array with options that will be passed to the hasher. What these options are depends
89+
on the active hasher.
90+
91+
`AngryBytes\Hash\Hash::matchesShortHash()` is replaced by `AngryBytes\Hash\Hash::verifyShortHash()` this methods
92+
accepts three arguments (`$data`, `$hash` and `$options`) just like `AngryBytes\Hash\Hash::verify()`.
93+
94+
### Minor Changes
95+
96+
* Scalar values passed to `hash()` and `shortHash()` are no longer serialized.
97+
* `AngryBytes\Hash::compare()` now uses PHP native (timing attack safe) `hash_equals()` function.
98+
* Fixed namespace issues for `AngryBytes\Hash\HMAC`.
99+
* `AngryBytes\Hash\Hash` now implements a `__call()` method that dynamically passes
100+
methods to the active hasher. This allows you to perform calls such as `AngryBytes\Hash::hash($string, ['cost' => 15]);`
101+
without having to call `AngryBytes\Hash::getHasher()` first.
102+
103+
### Upgrading
104+
105+
Please refer to the [upgrade notes](UPGRADING.md).
106+
107+
### Deprecated & Removed Components
108+
109+
* `AngryBytes\Hash\RandomString` has been removed. Better open-source random string generation
110+
libraries are available to do this.
111+
112+
## 1.0.2
113+
Valid Blowfish salts (22 char long composed of ./A-Za-z0-9 characters only) are now used as the salt as-is instead
114+
of md5-ed and substring-ed.
115+
116+
## 1.0.1
117+
Adding travis build status and scrutinizer code qual. img. to readme
118+
119+
## 1.0.0
120+
Initial release

README.md

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,54 @@
11
# AngryBytes Hash
22

3+
[![Author](http://img.shields.io/badge/author-@angrybytes-blue.svg?style=flat-square)](https://twitter.com/angrybytes)
4+
[![Software License](https://img.shields.io/badge/license-proprietary-brightgreen.svg?style=flat-square)](LICENSE.md)
35
[![Build Status](https://travis-ci.org/AngryBytes/hash.svg?branch=master)](https://travis-ci.org/AngryBytes/hash)
46
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/AngryBytes/hash/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/AngryBytes/hash/?branch=master)
57

68
A simple PHP library that simplifies cryptographical hashing. It provides an
79
object oriented interface to a variety of hashing methods.
810

9-
## Contents
11+
## Requirements
12+
13+
* PHP `5.6.0` or `PHP 7.0` (recommended)
14+
15+
## Installation
16+
17+
Installation is done via Composer: `composer require angrybytes/hash`.
18+
19+
## Components
1020

1121
### Hash
1222

13-
`AngryBytes\Hash\Hash` is the main hasher class. It uses one of the `Hashers` to do the work.
23+
`AngryBytes\Hash\Hash` is the main hasher class and acts as a helper wrapper
24+
around hashers (i.e. `AngryBytes\Hash\HasherInterface` implementations).
25+
26+
Some of the main features of this component:
1427

15-
Available hashers are:
28+
* Hash strings and/or passwords.
29+
* Create short hashes (e.g. used for identification).
30+
* Compare strings/hashes using a time-safe method.
31+
* Verify a string against a hash using the configured hasher.
32+
33+
### Hashers
34+
35+
This library comes with a set of hashers to be utilised by this hash component (or
36+
to be used on their own):
1637

1738
* `AngryBytes\Hash\Hasher\BlowFish`
1839
* `AngryBytes\Hash\Hasher\MD5`
19-
20-
In addition this class can compare strings/hashes using a time-safe method.
40+
* `AngryBytes\Hash\Hasher\Password`
2141

2242
### HMAC
2343

2444
`AngryBytes\Hash\HMAC` can be used to generate
2545
[HMAC's](http://en.wikipedia.org/wiki/Hash-based_message_authentication_code)
2646
for string messages.
2747

28-
### Random Strings
48+
## Contributing
49+
50+
Before contributing to this project, please read the [contributing notes](CONTRIBUTING.md).
51+
52+
## License
2953

30-
Also included is a basic random string generator in
31-
`AngryBytes\Hash\RandomString`. It targets Unix systems with `/dev/urandom`
32-
available for now.
54+
Please refer to the [license file](LICENSE.md).

UPGRADING.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Upgrade Notes
2+
3+
This document lists important upgrade nodes and BC breaks per version.
4+
5+
## 2.0.0
6+
7+
### Update Hashing Values
8+
9+
If you are hashing multiple values you will need to change the way their are passed
10+
to the hasher. Instead of passing each variable separately you will need to pass
11+
them as an array. Like so:
12+
13+
```php
14+
15+
// Create a new Password Hasher
16+
$hasher = new \AngryBytes\Hash\Hash(
17+
new \AngryBytes\Hash\Hasher\Password
18+
);
19+
20+
// Old
21+
$hash = $hasher->hash('foo', 'bar', ['foo', 'bar']);
22+
23+
// New
24+
$hash = $hasher->hash([
25+
'foo', 'bar', ['foo', 'bar']
26+
]);
27+
```
28+
29+
The same principle applies to `Hash::shortHash()`.
30+
31+
### Update Hash Validation
32+
33+
In the previous version hash validation would be done by creating a hash and comparing
34+
it to the existing hash. Now, you can simple pass the value(s) to hash and the
35+
existing hash to methods: `verify()` or `verfiyShortHash()`.
36+
37+
```php
38+
// Create a new Password Hasher
39+
$hasher = new \AngryBytes\Hash\Hash(
40+
new \AngryBytes\Hash\Hasher\Password
41+
);
42+
43+
// The origin and hashed values
44+
$valueToHash = '...'
45+
$existingHash = '...';
46+
47+
// Old
48+
$isValid = \AngryBytes\Hash\Hash::compare(
49+
$hasher->hash($valueToHash),
50+
$existingHash
51+
);
52+
53+
// New
54+
$isValid = $hasher->verify($valueToHash, $existingHash)
55+
```
56+
57+
And for short hash comparison:
58+
59+
```php
60+
// Create a new Password Hasher
61+
$hasher = new \AngryBytes\Hash\Hash(
62+
new \AngryBytes\Hash\Hasher\Password
63+
);
64+
65+
// Old
66+
if (Hash::matchShortHash($hasher->shortHash($value), $existingShortHash)) {
67+
// Hash is valid
68+
}
69+
70+
// New
71+
if ($hasher->verifyShortHash($value, $existingShortHash)) {
72+
// Hash is valid
73+
}
74+
```

composer.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@
2727
"AngryBytes\\Hash": "src"
2828
}
2929
},
30+
"require": {
31+
"php": "~5.6 || ~7.0"
32+
},
3033
"require-dev": {
31-
"phpunit/phpunit": "3.7.x"
34+
"phpunit/phpunit" : "~5.4.0"
3235
}
3336
}

0 commit comments

Comments
 (0)