# Adding a simple API for secure password hashing?

- Thread: https://externals.io/message/60812
- Original archive: https://news-web.php.net/php.internals/60812
- Started by Nikita Popov on 2012-06-13T21:31:35+00:00
- Messages: 38
- Page 1 of 2: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/60812.md?page=2
- 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

---

## #60812 — Nikita Popov — 2012-06-13T21:31:35+00:00

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

Hi internals!

Recent incidents have shown that even very large websites still don't
get how to do password hashing properly. The sha1 hashes used by
Linkedin et al can be easily cracked even by amateurs without special
hardware.

What could be the reason for this? Why don't people use bcrypt? It is
being recommended already for *years*, but still most people don't
seem to make use of it.

I think the reason is that it is incredibly hard to use `crypt()`
correctly, mainly for the following reasons:

* For many people the syntax is hard to grasp. The hashing algorithm
is specified as the salt parameter, which is somewhat non-obvious (at
least for me).
* The fact that you verify a password using $hash == crypt($password,
$hash) is equally non-obvious.
* Generating correct salts for bcrypt is quite complicated. It is
encoded in some strange base64 format, thus requiring an additional
function to create it. Additionally it isn't particularly easy to
fetch the random bytes for the salt as you have to check several
possibilities for a cross-platform solution (mcrypt initialization
vector, openssl, /dev/*random, mt_rand etc).

Correctly hashing a password with bcrypt thus requires about a hundred
lines of code. So one either has to import a library (and strangely it
seems that people don't like to do that!) or has to roll your own
(usually implementing some part incorrectly...)

Obviously it's somewhat tempting to use a one-liner `sha1()` hash
instead of a hundred line bcrypt hash.

So, wouldn't it be better if PHP provided an easy to use API for
secure password hashes natively? So you just have to call a single
function, which magically handles everything for you (like salt
generation).

A simple sample API could be two functions password_hash($password)
and password_hash_verify($password, $hash). But it could just as well
be a fancy, extensible OOP API.

I think this would greatly improve the hashing situation for PHP.

Thanks,
Nikita

---

## #60813 — Gwynne Raskind — 2012-06-13T21:44:46+00:00

URL: https://externals.io/message/60812#60813 · In reply to: #60812

> Hi internals!
>
> Recent incidents have shown that even very large websites still don't
> get how to do password hashing properly. The sha1 hashes used by
> Linkedin et al can be easily cracked even by amateurs without special
> hardware.
>
> What could be the reason for this? Why don't people use bcrypt? It is
> being recommended already for *years*, but still most people don't
> seem to make use of it.
>
> I think the reason is that it is incredibly hard to use `crypt()`
> correctly, mainly for the following reasons:
>
> * For many people the syntax is hard to grasp. The hashing algorithm
> is specified as the salt parameter, which is somewhat non-obvious (at
> least for me).
> * The fact that you verify a password using $hash == crypt($password,
> $hash) is equally non-obvious.
> * Generating correct salts for bcrypt is quite complicated. It is
> encoded in some strange base64 format, thus requiring an additional
> function to create it. Additionally it isn't particularly easy to
> fetch the random bytes for the salt as you have to check several
> possibilities for a cross-platform solution (mcrypt initialization
> vector, openssl, /dev/*random, mt_rand etc).
>
> Correctly hashing a password with bcrypt thus requires about a hundred
> lines of code. So one either has to import a library (and strangely it
> seems that people don't like to do that!) or has to roll your own
> (usually implementing some part incorrectly...)
>
> Obviously it's somewhat tempting to use a one-liner `sha1()` hash
> instead of a hundred line bcrypt hash.
>
> So, wouldn't it be better if PHP provided an easy to use API for
> secure password hashes natively? So you just have to call a single
> function, which magically handles everything for you (like salt
> generation).
>
> A simple sample API could be two functions password_hash($password)
> and password_hash_verify($password, $hash). But it could just as well
> be a fancy, extensible OOP API.
>
> I think this would greatly improve the hashing situation for PHP.
>
> Thanks,
> Nikita

Strong +1 on this. I'd suggest writing an RFC.

-- Gwynne

---

## #60814 — Arvids Godjuks — 2012-06-13T22:01:36+00:00

URL: https://externals.io/message/60812#60814 · In reply to: #60812

I would definetly like that a lot to be the case. bcrypt is kind'a cryptic
and information about cryptography on the internet is not so informative
and are not in abundance.

---

## #60815 — Stas Malyshev — 2012-06-13T22:34:11+00:00

URL: https://externals.io/message/60812#60815 · In reply to: #60812

Hi!

> So, wouldn't it be better if PHP provided an easy to use API for
> secure password hashes natively? So you just have to call a single
> function, which magically handles everything for you (like salt
> generation).

Yes. The fact that `crypt()` doesn't allow to generate salt automatically
for non-default algorithms leads to people either defaulting to weaker
md5crypt or doing salt generation manually, which is dangerous. So I
think we need two things here:

1. An RFC for generic password hashing function (probably in hash, but
can be standalone too) improving on `crypt()`). The start with pbkdf2
looks good, but if we could intergate all possible ways it'd be nicer.

2. A patch (and RFC if necessary) for `crypt()` to allow it to generate
salts for non-default algorithms.

-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #60818 — Thomas Hruska — 2012-06-14T04:02:16+00:00

URL: https://externals.io/message/60812#60818 · In reply to: #60812

> Hi internals!
>
> Recent incidents have shown that even very large websites still don't
> get how to do password hashing properly. The sha1 hashes used by
> Linkedin et al can be easily cracked even by amateurs without special
> hardware.
>
> What could be the reason for this? Why don't people use bcrypt? It is
> being recommended already for *years*, but still most people don't
> seem to make use of it.

The real problem is this:

Writing a login system is a "rite of passage" for every web programmer 
and the majority of tutorials out there are using `md5()`/sha1() without 
salts.  Get programmers using trusted, secure systems and we'll start 
seeing these problems vanish.  This is a social engineering issue, not a 
technical one.

http://cubicspot.blogspot.com/2012/05/dear-web-developers-stop-making-login.html


> I think the reason is that it is incredibly hard to use `crypt()`
> correctly, mainly for the following reasons:
>
> * For many people the syntax is hard to grasp. The hashing algorithm
> is specified as the salt parameter, which is somewhat non-obvious (at
> least for me).
> * The fact that you verify a password using $hash == crypt($password,
> $hash) is equally non-obvious.
> * Generating correct salts for bcrypt is quite complicated. It is
> encoded in some strange base64 format, thus requiring an additional
> function to create it. Additionally it isn't particularly easy to
> fetch the random bytes for the salt as you have to check several
> possibilities for a cross-platform solution (mcrypt initialization
> vector, openssl, /dev/*random, mt_rand etc).

You forgot:

* Prior to PHP 5.3.x, certain key algorithms for bcrypt support were not 
necessarily available in `crypt()`.

* Some people are not a fan of the output of `crypt()` or the lack of 
input controls.


Other thoughts:  `mt_rand()` does not qualify as random.  If you need 
random bytes, consider using CSPRNG 
(http://barebonescms.com/documentation/csprng/).

-- 
Thomas Hruska
CubicleSoft President

Barebones CMS is a high-performance, open source content management 
system for web developers operating in a team environment.

An open source CubicleSoft initiative.
Your choice of a MIT or LGPL license.

http://barebonescms.com/

---

## #60822 — Daniel Macedo — 2012-06-14T12:26:05+00:00

URL: https://externals.io/message/60812#60822 · In reply to: #60812

Hi Nikita,

I think you might just get everyone behind this; easily!

However, I'd like to throw in scrypt as well. Thoughts?

Stas has the right approach, not only should the methods be simplified and
platform/algorithm agnostic but have a proper salt built in (there are a
few CSPRNG implementations around), I've seen salts used from numbers to
md5's to just being skipped altogether.

~ Daniel Macedo

---

## #60823 — Anthony Ferrara — 2012-06-14T13:11:55+00:00

URL: https://externals.io/message/60812#60823 · In reply to: #60822

Daniel,

> However, I'd like to throw in scrypt as well. Thoughts?

Yes, that's something to include for sure. I've actually been working
on the side on an implementation of scrypt to sit next to my pbkdf2
proposal as hash_scrypt (as the native function, so that it can be
used natively (without the salt generation component)...

> Stas has the right approach, not only should the methods be simplified and
> platform/algorithm agnostic but have a proper salt built in (there are a
> few CSPRNG implementations around), I've seen salts used from numbers to
> md5's to just being skipped altogether.

Well, just to be clear, a salt does not need a CSPRNG. All it needs to
be is reasonably unique. In fact, I wouldn't make it CS, as that would
deplete the available entropy in the system for CSPRNG generation.

So in practice, a normal PRNG will suffice. With that said, `mt_rand()`
is not enough. It should be a moderately good PSRNG. It just doesn't
need to be CS. If mcrypt is available, DEV_URANDOM would be a good
place to get entropy.

Or, we could implement a system like I did in
https://github.com/ircmaxell/PHP-CryptLib/tree/master/lib/CryptLib/Random
that follows RFC4086: http://tools.ietf.org/html/rfc4086#section-5.2
Where it mixes together several sources of weak and moderate strength
PRNG...



On another note, I had started an implementation of this yesterday. So
far, I see two "clean" ways of doing it. We could do it class based (I
put it on SPL because it's more of a library addition):

interface \SPL\Password {
    public function hash($password);
    public function verify($password, $hash);
}

class \SPL\Password\BCrypt implements \SPL\Password {
    public function __construct($cost = 15){}
    public function hash($password) {
        // Work involving `crypt()`
    }
    public function verify($password, $hash) {
        // Work involving `crypt()`
    }
}

Or, a more procedural approach, with a single "dispatching" function

function password_hash($password, $algorithm = PASSWORD_BLOWFISH,
$options = array()) {
}

function password_verify($password, $hash, $algorithm =
PASSWORD_BLOWFISH, $options = array()) {
}

function password_register($algorithm_name, $hashFunc, $verifyFunc) {
}

The one big issue that I ran into was in registering a namespaced
class into SPL. The SPL class functions aren't designed to handle
namespaced classes as far as I could tell. So we'd have to make a
patch to that first to add macros to support namespaced code...

Thoughts?

Anthony

---

## #60824 — Peter Lind — 2012-06-14T13:27:37+00:00

URL: https://externals.io/message/60812#60824 · In reply to: #60823

* snip*

> > […]
>
> Well, just to be clear, a salt does not need a CSPRNG. All it needs to
> be is reasonably unique. In fact, I wouldn't make it CS, as that would
> deplete the available entropy in the system for CSPRNG generation.

Whether or not a CSPRNG is needed depends on what you're doing, your
needed level of security. Perhaps add a parameter to control this, so
it would be possible to make use of this function even if you need the
maximum level of security? If it's not available, the function should
fail in some suitable fashion.

*snip*

> Or, we could implement a system like I did in
> https://github.com/ircmaxell/PHP-CryptLib/tree/master/lib/CryptLib/Random
> that follows RFC4086: http://tools.ietf.org/html/rfc4086#section-5.2
> Where it mixes together several sources of weak and moderate strength
> PRNG...

Will the entropy multiply by mixing sources? I.e. will the result be
"more random"? Won't it just be as random as the most random source?

Other than that, the SPL version seems like a nice idea.

Regards
Peter

-- 
<hype>
WWW: plphp.dk / plind.dk
LinkedIn: plind
BeWelcome/Couchsurfing: Fake51
Twitter: kafe15
</hype

---

## #60826 — Anthony Ferrara — 2012-06-14T13:35:57+00:00

URL: https://externals.io/message/60812#60826 · In reply to: #60824

Peter,

> Whether or not a CSPRNG is needed depends on what you're doing, your
> needed level of security. Perhaps add a parameter to control this, so
> it would be possible to make use of this function even if you need the
> maximum level of security? If it's not available, the function should
> fail in some suitable fashion.

For password hashing, it won't ever be needed for the salt. The salt
is not a secret in the context of cryptography. But, on that note, if
we were adding a stronger PRNG generator, it would be good to expose
it natively. And that native exposure would likely take a parameter
for CS-safe PRNG...

Just my $0.02...

> *snip*
>
> > […]
>
> Will the entropy multiply by mixing sources? I.e. will the result be
> "more random"? Won't it just be as random as the most random source?

No, it will not multiply. It can in practice increase from the
strongest source. But it will never be *weaker* than the strongest
source. The reason for a mixing function like that, is that you're
pulling entropy from multiple sources. So if a single source is
compromised (say mt_rand is compromised with a known seed value), it
doesn't reduce the overall strength of the generated value. If the
strongest source is compromised, it will still be at least as strong
as the next weakest source...

Anthony

> Other than that, the SPL version seems like a nice idea.
>
> Regards
> Peter
>
> --
> <hype>
> WWW: plphp.dk / plind.dk
> LinkedIn: plind
> BeWelcome/Couchsurfing: Fake51
> Twitter: kafe15
> </hype

---

## #60827 — Thomas Hruska — 2012-06-14T14:19:59+00:00

URL: https://externals.io/message/60812#60827 · In reply to: #60823

> Daniel,
>
> > […]
>
> Well, just to be clear, a salt does not need a CSPRNG. All it needs to
> be is reasonably unique. In fact, I wouldn't make it CS, as that would
> deplete the available entropy in the system for CSPRNG generation.
>
> So in practice, a normal PRNG will suffice. With that said, `mt_rand()`
> is not enough. It should be a moderately good PSRNG. It just doesn't
> need to be CS. If mcrypt is available, DEV_URANDOM would be a good
> place to get entropy.
>
> Or, we could implement a system like I did in
> https://github.com/ircmaxell/PHP-CryptLib/tree/master/lib/CryptLib/Random
> that follows RFC4086: http://tools.ietf.org/html/rfc4086#section-5.2
> Where it mixes together several sources of weak and moderate strength
> PRNG...

This:

http://barebonescms.com/documentation/csprng/

Takes a different approach.  Generate one or more stored root seeds and 
then use those seeds to generate as much data as is needed without 
risking loss of entropy.  It also accepts extra entropy sources as input 
- even weak sources such as an incrementing integer or serialized 
user-submitted data - to further enhance the output.

Adding more random sources of information to PHP is a good thing.  If 
something like what is being discussed is developed, it will merely 
become one more source for root seed generation.  The more the merrier. 
  Good sources of entropy are hard to come by.

One thing I would like to recommend is add to the documentation that 
certain functions are inappropriate for specific use cases and recommend 
alternative solutions.  A lot of people out there think `rand()` and 
 `mt_rand()` are suitable for security.  Maybe have a specific page in the 
PHP documentation dedicated to covering random string and number 
generation and link to that page from various function pages.

-- 
Thomas Hruska
CubicleSoft President

Barebones CMS is a high-performance, open source content management 
system for web developers operating in a team environment.

An open source CubicleSoft initiative.
Your choice of a MIT or LGPL license.

http://barebonescms.com/

---

## #60828 — Peter Lind — 2012-06-14T14:26:07+00:00

URL: https://externals.io/message/60812#60828 · In reply to: #60826

> Peter,
>
> > […]
>
> For password hashing, it won't ever be needed for the salt. The salt
> is not a secret in the context of cryptography. But, on that note, if
> we were adding a stronger PRNG generator, it would be good to expose
> it natively. And that native exposure would likely take a parameter
> for CS-safe PRNG...

I would say it really depends upon the project. The salt can not only
protect against rainbow tables and password hash collisions, if it is
unknown to an attacker then it essentially acts to further strengthen
the hash by vastly expanding the keyspace. Supposing an attacker is
trying to get at the password for just one user account (say, admin)
and the hashed password is available - if the salt can be
predicted/guessed, then the keyspace is reduced to that of an unsalted
password and you can run a dictionary attack on the hash. If, on the
other hand, the salt is unpredictable and you don't have access to it,
there is no way to run a dictionary attack (offline, that is). The
security here depends upon storage as well, but the point remains - a
salt isn't by default something you can make public knowledge.

It might be a theoretical concern for most people and the people
really wanting the extra level of security would probably know well
enough how to get exactly what they need - but if provisions are made
so you could reuse the same function you might also be able to educate
developers better. I.e. make it easy to do the right thing and more
people will do it.

Regards
Peter

-- 
<hype>
WWW: plphp.dk / plind.dk
LinkedIn: plind
BeWelcome/Couchsurfing: Fake51
Twitter: kafe15
</hype

---

## #60829 — Anthony Ferrara — 2012-06-14T14:50:09+00:00

URL: https://externals.io/message/60812#60829 · In reply to: #60827

Thomas,

> This:
>
> http://barebonescms.com/documentation/csprng/
>
> Takes a different approach.  Generate one or more stored root seeds and then
> use those seeds to generate as much data as is needed without risking loss
> of entropy.  It also accepts extra entropy sources as input - even weak
> sources such as an incrementing integer or serialized user-submitted data -
> to further enhance the output.

Actually, I would not call that CS. Where's the white paper for the
algorithm? Where's the RFC? Just because you take data from a lot of
sources does not make it CS... And just putting the *kitchen sink*
into a single sha512 hash does not either. The vast majority of the
data that's being called entropy is purely static on the system (page
to page won't change).

Especially for something that's going into core, I'd suggest sticking
to approved, vetted algorithms. If it doesn't have an RFC or a
reviewed white-paper, I would avoid it.

Additionally, it's pushing all of the "entropy sources" into a single
hash bucket. I'd much rather see it push each one through a hmac round
with the existing data. That way, the relationship between a specific
source and the overall result is complex. It's not just complex in
relation to other data, but also into the algorithm itself...

> Adding more random sources of information to PHP is a good thing.  If
> something like what is being discussed is developed, it will merely become
> one more source for root seed generation.  The more the merrier.  Good
> sources of entropy are hard to come by.

Definitely agree...

> One thing I would like to recommend is add to the documentation that certain
> functions are inappropriate for specific use cases and recommend alternative
> solutions.  A lot of people out there think `rand()` and `mt_rand()` are
> suitable for security.  Maybe have a specific page in the PHP documentation
> dedicated to covering random string and number generation and link to that
> page from various function pages.

Sounds good to me...

Anthony

---

## #60830 — Anthony Ferrara — 2012-06-14T14:58:20+00:00

URL: https://externals.io/message/60812#60830 · In reply to: #60828

Peter,

> I would say it really depends upon the project. The salt can not only
> protect against rainbow tables and password hash collisions, if it is
> unknown to an attacker then it essentially acts to further strengthen
> the hash by vastly expanding the keyspace.

That's not true. There are two types of secure algorithms in
cryptography. Those that are kept secure by a secret, and those that
are secure by effort. Hashing is an effort based algorithm. It's
difficult to reverse, so you need to brute force, expending a lot of
effort in the process... Salts are designed to make that brute forcing
non-amortizable, only (meaning that the effort put in to brute force
one hash can't be applied to another). The way they are used in the
algorithms shows that. They are even stored directly with the hash in
a number of implementations (crypt being a key one). That should point
out how the security that a salt adds does not depend on it being
secret.

> Supposing an attacker is
> trying to get at the password for just one user account (say, admin)
> and the hashed password is available - if the salt can be
> predicted/guessed, then the keyspace is reduced to that of an unsalted
> password and you can run a dictionary attack on the hash. If, on the
> other hand, the salt is unpredictable and you don't have access to it,
> there is no way to run a dictionary attack (offline, that is). The
> security here depends upon storage as well, but the point remains - a
> salt isn't by default something you can make public knowledge.

Then it's not a salt. And unless you *really* know what you're doing,
it's not worth it, and at best you're not making it more secure (and
at worst, you're significantly reducing the security). Remember,
security through obscurity is not security. Check out this post, and
the comments from experts:
http://blog.ircmaxell.com/2012/04/properly-salting-passwords-case-against.html

> It might be a theoretical concern for most people and the people
> really wanting the extra level of security would probably know well
> enough how to get exactly what they need - but if provisions are made
> so you could reuse the same function you might also be able to educate
> developers better. I.e. make it easy to do the right thing and more
> people will do it.

No, if people want the extra level of security, they should then
encrypt the hash with a secure key before storing it. Note that 2
algorithms would be in place, one proof of work, and one dependent
upon a secret. Trying to combine them because one parameter looks like
it could be a secret is not the way to go...

Anthony

---

## #60831 — keisial@gmail.com — 2012-06-14T15:50:23+00:00

URL: https://externals.io/message/60812#60831 · In reply to: #60828

> I would say it really depends upon the project. The salt can not only
> protect against rainbow tables and password hash collisions, if it is
> unknown to an attacker then it essentially acts to further strengthen
> the hash by vastly expanding the keyspace. Supposing an attacker is
> trying to get at the password for just one user account (say, admin)
> and the hashed password is available - if the salt can be
> predicted/guessed, then the keyspace is reduced to that of an unsalted
> password and you can run a dictionary attack on the hash. If, on the
> other hand, the salt is unpredictable and you don't have access to it,
> there is no way to run a dictionary attack (offline, that is). The
> security here depends upon storage as well, but the point remains - a
> salt isn't by default something you can make public knowledge.
>
> It might be a theoretical concern for most people and the people
> really wanting the extra level of security would probably know well
> enough how to get exactly what they need - but if provisions are made
> so you could reuse the same function you might also be able to educate
> developers better. I.e. make it easy to do the right thing and more
> people will do it.
May I ask how would you end up at the situation where the attackers have
the password hashes but not the salt?

Any process which needs to read the password hashes will also need
knowledge of the salt. Thus an attacker would most likely also know both.
That's precisely how salts are designed to work.

I admit you could have a common salt for all users stored in php and
only a leak of the database. But such salt would most likely be provided
by the user, generated using a different program... expected to be secure.
Using a shared salt is worse than a uniqe salt per user, so that's not
something to promote either.
You wouldn't be "educating in the right way".

---

## #60835 — Peter Lind — 2012-06-14T16:33:15+00:00

URL: https://externals.io/message/60812#60835 · In reply to: #60831

*snip*

> May I ask how would you end up at the situation where the attackers have
> the password hashes but not the salt?
>
> Any process which needs to read the password hashes will also need
> knowledge of the salt. Thus an attacker would most likely also know both.
> That's precisely how salts are designed to work.

If your salts are not stored with your password hashes, then an sql
injection that would leak your password hashes would not leak the
salts. The recent database leaks come to mind: had they only contained
password hashes but no salts (I know the hashes were unsalted, but
*had* they been salted ...) attackers would have faced an impossible
task trying to bruteforce even just one hash. Otherwise, you'd be able
to focus on a given account (an admin account comes to mind) and spend
all your efforts on that using the typical options.

As pointed out once or twice, for most people/purposes, it's a
theoretical discussion. That doesn't mean it shouldn't be taken into
consideration though (people rarely break into your house where you
expect them to).


> I admit you could have a common salt for all users stored in php and
> only a leak of the database. But such salt would most likely be provided
> by the user, generated using a different program... expected to be secure.
> Using a shared salt is worse than a uniqe salt per user, so that's not
> something to promote either.
> You wouldn't be "educating in the right way".

And I'm obviously not advocating a shared salt (at least, I wasn't
thinking I was, especially seeing as I asked for a parameter in
function to make sure that salts would be more random).

Regards
Peter


-- 
<hype>
WWW: plphp.dk / plind.dk
LinkedIn: plind
BeWelcome/Couchsurfing: Fake51
Twitter: kafe15
</hype

---

## #60839 — Kris Craig — 2012-06-14T18:42:39+00:00

URL: https://externals.io/message/60812#60839 · In reply to: #60812

On Wed, Jun 13, 2012 at 2:31 PM, Nikita Popov <nikita.ppv@googlemail.com>wrote:

> Hi internals!
>
> Recent incidents have shown that even very large websites still don't
> get how to do password hashing properly. The sha1 hashes used by
> Linkedin et al can be easily cracked even by amateurs without special
> hardware.
>

LinkedIn was using sha1?!  Are you fucking serious??  I think it's time for
me to change my password there to something I'm *not* using anywhere else
lol.

At this rate, tomorrow are we going to learn that Gmail uses md5 and that
Facebook passwords are stored in plaintext files under the HTTP root?....


Anyway, BIG +1 on this RFC!

--Kris

---

## #60846 — Herman Radtke — 2012-06-15T16:23:33+00:00

URL: https://externals.io/message/60812#60846 · In reply to: #60839

This userland library already solves all the issues you outlined with
bcrypt: http://www.openwall.com/phpass/

The API is very easy to use, has been around for a while and has a
number of detailed articles that explain how to use it.

-- 
Herman Radtke
hermanradtke@gmail.com | http://hermanradtke.com

---

## #60856 — Pierre Joye — 2012-06-16T11:51:44+00:00

URL: https://externals.io/message/60812#60856 · In reply to: #60846

hi!
hi!


> This userland library already solves all the issues you outlined with
> bcrypt: http://www.openwall.com/phpass/
>
> The API is very easy to use, has been around for a while and has a
> number of detailed articles that explain how to use it.

And that one is already used by many projects as well.

Cheers,
-- 
Pierre

@pierrejoye | http://blog.thepimp.net | http://www.libgd.org

---

## #60859 — Anthony Ferrara — 2012-06-16T12:41:22+00:00

URL: https://externals.io/message/60812#60859 · In reply to: #60846

Herman,

> This userland library already solves all the issues you outlined with
> bcrypt: http://www.openwall.com/phpass/

That library is not without its issues. For example, if you ask for a
portable hash, it gives you a custom algorithm instead of bcrypt.
That's because the library is php4 compatible. So for modern versions
of PHP (5.3+), it produces an unnecessarily weak hash.

In addition, the custom hash function that it uses is fairly weak. It
uses md5 as its primitive (because in php4 that's all that's
available), which while not the end of the world, could be improved.
It also does a simple feedback loop on hash the hash function for the
iterations. This is good, but could be better by using hash_hmac which
internally does two hash rounds per call, and feeding back more state
into the loop (Like PBKDF2 does).

It's not bad enough that if you're already using it you should go
running to replace it (not at all). But if you are starting a new
project, stick to bcrypt, PBKDF2, crypt_sha512, scrypt, etc...

If you want some background on it: http://drupal.org/node/1201444

The reason that I am bringing it up, is that if we're pulling it in
core, we should understand the limitations...

Anthony

---

## #60860 — Pierre Joye — 2012-06-16T13:39:35+00:00

URL: https://externals.io/message/60812#60860 · In reply to: #60859

hi Anthony,

Adding Alex to the loop as his insight will be unvaluable in this thread.



> > […]
>
> That library is not without its issues. For example, if you ask for a
> portable hash, it gives you a custom algorithm instead of bcrypt.
> That's because the library is php4 compatible. So for modern versions
> of PHP (5.3+), it produces an unnecessarily weak hash.

Because it was exciting before.

However the point here is not the implementation but the APIs.

To be honest I am not a big fan of providing such an API in the core
as no matter the default implementation, it will become obsolete soon
or later. And changing the default brings its lot of issues and BC
problems.

That being said, it seems that we may not have the choice anyway so
having a well designed and implemented API for password (and related
or similar areas) generations may be a good thing.


Cheers,
-- 
Pierre

@pierrejoye | http://blog.thepimp.net | http://www.libgd.org

---

## #60862 — keisial@gmail.com — 2012-06-16T15:42:28+00:00

URL: https://externals.io/message/60812#60862 · In reply to: #60860

> However the point here is not the implementation but the APIs.
>
> To be honest I am not a big fan of providing such an API in the core
> as no matter the default implementation, it will become obsolete soon
> or later. And changing the default brings its lot of issues and BC
> problems.
>
> That being said, it seems that we may not have the choice anyway so
> having a well designed and implemented API for password (and related
> or similar areas) generations may be a good thing.
The generated password hash should contain versioning information (such
as the $1$ for crypt), so `password_verify()` of later PHP versions will
be able
to correctly verify it, even after the default password hash changes
(set an older
type in php.ini if you don't want to use the new format).

---

## #60868 — Alexey Zakhlestin — 2012-06-17T13:58:33+00:00

URL: https://externals.io/message/60812#60868 · In reply to: #60812

> So, wouldn't it be better if PHP provided an easy to use API for
> secure password hashes natively? So you just have to call a single
> function, which magically handles everything for you (like salt
> generation).
> 
> A simple sample API could be two functions password_hash($password)
> and password_hash_verify($password, $hash). But it could just as well
> be a fancy, extensible OOP API.

I guess SCrypt binding could be implemented.
http://www.tarsnap.com/scrypt.html

That's the best available option at the moment.
http://stackoverflow.com/questions/1226513/whats-the-advantage-of-scrypt-over-bcrypt

It is BSD-licensed, so we can easily bundle it with PHP

For the reference, here's the Python binding: https://bitbucket.org/mhallin/py-scrypt/src

---

## #60873 — Pierre Joye — 2012-06-17T21:54:53+00:00

URL: https://externals.io/message/60812#60873 · In reply to: #60868

hi,



> I guess SCrypt binding could be implemented.
> http://www.tarsnap.com/scrypt.html

Using yet another dependency for that? Not good.

> That's the best available option at the moment.
> http://stackoverflow.com/questions/1226513/whats-the-advantage-of-scrypt-over-bcrypt

This post says the exact opposite, just saying :)

> It is BSD-licensed, so we can easily bundle it with PHP

Maybe nice to have in pecl.'

cheers,
-- 
Pierre

@pierrejoye | http://blog.thepimp.net | http://www.libgd.org

---

## #60877 — Alexey Zakhlestin — 2012-06-18T09:06:33+00:00

URL: https://externals.io/message/60812#60877 · In reply to: #60873

> > […]
> 
> Using yet another dependency for that? Not good.

That's easier and safer than implementing this on our own.

> 
> > […]
> 
> This post says the exact opposite, just saying :)

The post says, that SCrypt is better, because it is way harder to solve.
Bcrypt requires a lot of CPU, but SCrypt requires a lot of CPU + a lot of RAM

> > […]
> 
> Maybe nice to have in pecl.'

Sure, that's an option, but pecl won't help php to have default "state-of-art" password hashing toolset ;)

---

## #60878 — Pierre Joye — 2012-06-18T15:42:26+00:00

URL: https://externals.io/message/60812#60878 · In reply to: #60877

hi,



> The post says, that SCrypt is better, because it is way harder to solve.
> Bcrypt requires a lot of CPU, but SCrypt requires a lot of CPU + a lot of RAM

Ah right, I read it the other way 'round...

> > […]
>
> Sure, that's an option, but pecl won't help php to have default "state-of-art" password hashing toolset ;)

There is sadly only state-of-art-right-now password hashing methods.
We have to keep that in mind :)

Cheers,
-- 
Pierre

@pierrejoye | http://blog.thepimp.net | http://www.libgd.org

---

Next page: https://externals.io/message/60812.md?page=2
