2012/7/12 Anthony Ferrara <ircmax...@gmail.com>:
> Hello all,
>
> Since the discussion has died down around the concept, I have updated the
> RFC and moved it into Proposed (under discussion) status.
>
> I have updated the RFC to include a section on discussion points containing
> points that I know were raised but I felt were not closed (there was some
> debate or disagreement). I tried to include a simple description of both
> arguments, and the position the RFC currently takes and a brief reason why.
>
> https://wiki.php.net/rfc/password_hash
>
> Please have a look and provide any feedback!

Hello Anthony,

I like your RFC. I can say this, because I wrote a similar project
about a year ago as a PHP-class and came to the same results.
No, that's not correct: Nearly the same results! There are small gaps
between my results and the suggested. I explain in detail in order of
"feeled priority".

[I don't had a look into the current C implementation, because I want
to keep my mind clean from the needs of the C-developers side: I want
to focus on the PHP-developer side.]


1. The resulting string should have a version information. For example
the first char. the example hash will look like
"1$2y$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi",
instead of "$2y$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi"

Maybe it is legal to interpret a missing version as "this is version
1"? But it is important, that it has now a version for
future-compatibility. This is, becaus encryption is developed since I
program and will develop further within the next thousand years. With
a version-information we can guarantee that the algorithms can work,
even if the hash-format changes markable (because needed, because new
unforseeable aspects of encryption come in focus). In my project, this
version-information helped me to distinct between old password-hashes
and new ones.

[I think this is also a good argument against "password_hash() should
have no defaults", because this is a more than obvious sign to
everyone "hey, there could be a version 2, how will that look like?"]



2a) I'm not happy with the behavour to raise warnings. Maybe I'm
splitting hairs, but if there is one error, the chance is by
experience very big, that there is another. So, if a developer for
example will not check the results of password_hash(), false is stored
in the database. And if he makes a second error (and the chance is  as
said very big in this case), you may be able to log in with this or do
other ugly stuff. Don't say "impossible". I've seen things...

In my project I had really very good results, when I just throw
exceptions in the case that something goes wrong. This is the highly
visible sign for a bad developer, that he has made something wrong or
for a customer, installing a new version, that he now has a big
problem and should go back to the older version. I really want
exceptions here, because they prevent such missuse very effective and
cannot be overgone.

By minimim it should stop execution, if the password_hash() or
password_verify() is called wrong, because I think, this is more
secure than just to continue, which is in my eyes definitily a
mistake.

Maybe I'm wrong and this behaviour will make it possible to hack the
database? But I don't belive that...

With other words: I think how to deal with warnings in this
"potentially hazardous" methods needs a little bit more discussion and
I'm currently not satisfied with it, because it doesn't prevent stupid
errors.


2b) I don't like that the functions sometimes will return FALSE,
sometimes NULL. Not logical for PHP-developer and will lead by
guarantee to code which is checked wrong. Again: I would prefer to
fetch exceptions. If this is not possible I want either NULL or FALSE
as result for all functions, but not NULL or FALSE.


3a) I would await a function "password_algos()" (like hash_algos()),
which returns me all available algorithms.

The available algorithms should also be displayed in PHPINFO(). This
is because I need to check, if the current version has built it in.

3b) I don't like the encryption of the algorithm ("2y", WTF, what's
that? :) ). Look at the function hash_algos(). There are full
qualified names of algorithms. Why don't use just the names? Is it,
because of some more bytes needed? :) Ok, I mean: why not using a good
name, so that someone can guess what it is, without knowing the docs?
That's just my thinking as PHP-developer, because this is not logical
for me to encrypt the encryption-algorithm. :)

3c) I think about changes. Password algorithms are a thing of changing
over time. So I would like to have a function like
"password_algo_info($algo)", which returns me as a developer a
detailed information about what this algorithm needs to work propper
and what the full description of this is (including e.g. an url, where
I can look for more information), because I think that this is
eventually a thing, which is extended rapidly and the documentation is
to slow to go with it. Or you are working with an older version in
which the algo works different. Not very important and maybe needs
more discussion. But I think something is here better than nothing.
Again: very low prio!


4a) I don't like the hole CONSTANT-stuff. I don't want to have a
doozen of fixed CONSTANTS, because I don't need them. The only
constant is, that the list of constants will rise. :)
Ok, more serious: I really don't need a constant for a thing, which is
currently known to be changed in future. If the password is always
stored with the currently most secure algorithm I don't need that.

And as a developer this is, what I want! I don't want to care about
the details, I want to be sure, that this is the currently most secure
way to do it. That's what I want. I don't want to know, which
algorithms exists. I don't need to choose between them. I just use
them, because some smarter guys than me have thought thouroughly about
what is most secure. :)

I can not think about an situation where I need to set it in my code
under normal circumstances. And if I really need to choose an
algorithm, it is better a configurable option in my program, thats
just good style. (For example a configuration-file, or a call-option.)
A constant means: It is fixed in my code. That's good, if it doesn't
change.

Another example: if I need to choose the algorithm as an
administrator, I choose it in my admin-interface from a select-field.
The value is then stored as as string and not as a constant-name. I
need to create that list of available algorithms. I don't need
constants.

The only situations, where constants may be needed are, if you write a
converter or something like that and even in this case constants won't
make the code better or more secure, they only help to prevent silly
programming mistakes. The real mistakes are: Development and
Production have slightly different versions. Or you may have a big
problem, if your IDE is not matching to the used PHP-version. If you
have constants, you will never program arround that. If you don't you
need to think about how it would be self-configuring...

In short: No real need for constant (except that you get warnings, if
you take a constant, which is not available, but see above: If needed,
it will be in a config-file as text). It would be another situation,
if this would be a feature, which will not change much over the time.
But it will.

I need to generate displayable lists and more intuitive algorithm
names than just "2y".


4b) I don't like the idea to change a constant (PASSWORD_DEFAULT) with
a new version of PHP. This may break in some ugly situation your hole
PHP-update, because you didn't thought about this change. :)
Again: I think, that chhoosing the best algorithm should normally not
be the job of the developer. I don't see the need.
But to make it possible I suggest to have a function
"password_best_algo()" instead, which returns a name of
password_algos(). Why a function instead of a constant? You can add a
parameter "$version" to this function and in this case the function
returns the best algorithm for that version of a password-hash. I
think this is eventually important, but maybe I'm looking too far into
the future or forgot to think this completly through.


5. I added something like "is_password_hash()", to check, if a hash
has the right syntax (not semantic) to work with it. This prevents
internally also, that hashes with version 2 can work together with the
class for version 1.


6. This is hair-splitting again, but least important: I don't like the
name "password*" for the functions. This is because the functions
don't return a password. Impractical names will give (some less
experienced developers) wrong ideas of what the functions may do.

It should be clear: This is a hash-function, you fill in a password
and get a hash.

But "hash*" is already used. I have no good solution for that and it
is not quite important, but how would it be with "pwhash*", "phash*"
or "hashpass"? Something good to remember...
Maybe needs further discussion, but as said: Not so important, maybe
someone has a good idea...



Some comments to the discussion points:

password_make_salt() Is Not Needed: I like that function, because it
can be used to generate a random password(). Just google for "generate
password" to see what I mean.
It should have a third mode, where the "/"-char is not included for
that case, because it may make problems. Maybe it is also a good idea
that you can pass a string, which includes the allowed chars for this
function. And because it can be used for completly other things than
just hashes or passwords I think renaming or an alias would be useful
e.g. "str_random()". (UTF8?)

password_needs_rehash() is not needed: I think it's needed. Think
about 5 years from now: bcrypt() is found to be insecure. Now we have
to rebuild the hash. Not possible over night. Could be done while
logging in and checking if it needs rehashing with this function.



Again: This are only suggestions from the sight of an experienced
PHP-developer. It's totally clear, that you have another sight. But I
hope they are helpful.

Hope you are not too firm with me, I'm new to this list. :)

-- 
Alexander Aulbach

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to