# [VOTE] Hash_pbkdf2

- Thread: https://externals.io/message/61065
- Original archive: https://news-web.php.net/php.internals/61065
- Started by Anthony Ferrara on 2012-07-02T16:34:30+00:00
- Messages: 7
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #61065 — Anthony Ferrara — 2012-07-02T16:34:30+00:00

URL: https://externals.io/message/61065#61065

Hello all,

I've opened voting for the hash_pbkdf2 RFC adding `hash_pbkdf2()` to master:

https://wiki.php.net/rfc/hash_pbkdf2#vote

Thanks,

Anthony

---

## #61066 — Paul Dragoonis — 2012-07-02T16:38:11+00:00

URL: https://externals.io/message/61065#61066 · In reply to: #61065

I see no coding examples, just a function declaration.



> Hello all,
>
> I've opened voting for the hash_pbkdf2 RFC adding `hash_pbkdf2()` to master:
>
> https://wiki.php.net/rfc/hash_pbkdf2#vote
>
> Thanks,
>
> Anthony

---

## #61067 — Anthony Ferrara — 2012-07-02T16:50:00+00:00

URL: https://externals.io/message/61065#61067 · In reply to: #61066

Paul


> I see no coding examples, just a function declaration.

I've updated the RFC adding 2 examples.

Anthony

---

## #61074 — Sara Golemon — 2012-07-03T00:24:53+00:00

URL: https://externals.io/message/61065#61074 · In reply to: #61065

I'd like to see `hash_init()` support this mode as well (for completeness).
 Perhaps something like the following:

$ctx = hash_init("sha512", HASH_PBKDF2, $salt, array('length' => 32,
'iterations' => 5000));

The new fourth parameter being an overloadable options generic so that we
don't have an endless list of parameters for all the possible hashing types.

-Sara



> Hello all,
>
> I've opened voting for the hash_pbkdf2 RFC adding `hash_pbkdf2()` to master:
>
> https://wiki.php.net/rfc/hash_pbkdf2#vote
>
> Thanks,
>
> Anthony

---

## #61075 — Anthony Ferrara — 2012-07-03T00:49:03+00:00

URL: https://externals.io/message/61065#61075 · In reply to: #61074

Sara,


> I'd like to see `hash_init()` support this mode as well (for completeness).
>  Perhaps something like the following:
>
> $ctx = hash_init("sha512", HASH_PBKDF2, $salt, array('length' => 32,
> 'iterations' => 5000));
>
> The new fourth parameter being an overloadable options generic so that we
> don't have an endless list of parameters for all the possible hashing types.

The only problem that I have with this sort of implementation is that
the only way it would work is to buffer the entire input (each
hash_update call), and run it all at the end. That's because the data
(password) is used in every iteration, so there's no pre-computation
that can be done. And at that point, what's the benefit to it?

public function pbkdf2($algo, $password, $salt, $iterations, $length) {
        $size   = getHashBlockSize($hash);
        $len    = ceil($length / $size);
        $result = '';
        for ($i = 1; $i <= $len; $i++) {
            $tmp = hash_hmac($hash, $salt . pack('N', $i), $password, true);
            $res = $tmp;
            for ($j = 1; $j < $iterations; $j++) {
                $tmp  = hash_hmac($hash, $tmp, $password, true);
                $res ^= $tmp;
            }
            $result .= $res;
        }
        return substr($result, 0, $length);
    }

Contrast that to a normal hash function (used by the current
hash_init) which iterates over blocks of input, and once it's done
with a block, it doesn't need it anymore (which is where using
something like hash_init/hash_update can make sense on large input).

Additionally, hmac only uses the message in a single hash, so it can
be streamed in as well (pre-compute the earlier hashes/data, stream
the intermediate hash, then hash the final one).

So while it could be added (just make hash_update buffer into a
context, then have hash_final actually run the derivation), I'm not
sure it makes sense to add it there.

Thoughts?

Anthony

---

## #61076 — Sara Golemon — 2012-07-03T02:37:10+00:00

URL: https://externals.io/message/61065#61076 · In reply to: #61075

> Sara,
>
> 
> > […]
> types.
>
> The only problem that I have with this sort of implementation is that
> the only way it would work is to buffer the entire input (each
> hash_update call), and run it all at the end. That's because the data
> (password) is used in every iteration, so there's no pre-computation
> that can be done. And at that point, what's the benefit to it?
>
> public function pbkdf2($algo, $password, $salt, $iterations, $length) {
>         $size   = getHashBlockSize($hash);
>         $len    = ceil($length / $size);
>         $result = '';
>         for ($i = 1; $i <= $len; $i++) {
>             $tmp = hash_hmac($hash, $salt . pack('N', $i), $password,
> true);
>             $res = $tmp;
>             for ($j = 1; $j < $iterations; $j++) {
>                 $tmp  = hash_hmac($hash, $tmp, $password, true);
>                 $res ^= $tmp;
>             }
>             $result .= $res;
>         }
>         return substr($result, 0, $length);
>     }
>
> Contrast that to a normal hash function (used by the current
> hash_init) which iterates over blocks of input, and once it's done
> with a block, it doesn't need it anymore (which is where using
> something like hash_init/hash_update can make sense on large input).
>
> Additionally, hmac only uses the message in a single hash, so it can
> be streamed in as well (pre-compute the earlier hashes/data, stream
> the intermediate hash, then hash the final one).
>
> So while it could be added (just make hash_update buffer into a
> context, then have hash_final actually run the derivation), I'm not
> sure it makes sense to add it there.
>
> Thoughts?
>
> Anthony
>

Ah, wasn't clear on how pbkdf2 worked.  Your argument makes total sense.
Thanks for explaining it. :)

---

## #61119 — Anthony Ferrara — 2012-07-10T14:14:16+00:00

URL: https://externals.io/message/61065#61119 · In reply to: #61076

Hey all,

The voting phase has ended for hash_pbkdf2, and it has passed with a vote
of 8:0. I've moved the RFC into Accepted state, and will merge the PR today
into master, then move the RFC into Implemented.

Thanks!

Anthony



>
>
> On Mon, Jul 2, 2012 at 5:49 PM, Anthony Ferrara <ircmaxell@gmail.com>wrote:
>
> > […]
>
> Ah, wasn't clear on how pbkdf2 worked.  Your argument makes total sense.
> Thanks for explaining it. :)
