From: Paul Johnston on
Hi,

I am creating an intranet web application that will authenticate with
user name and password. Obviously, I want to store the passwords
hashed. This is only a defence-in-depth mechanism - I'm planning on
the hashes remaining secret, unless there is a database compromise.
The threat profile is somewhat different to, say, WPA-PSK.

There are a number of potential algorithms to do this - scrypt,
pbkdf2, bcrypt, etc. Is there any guide on which is best to use? Or
are they all largely equal? I don't want to go overboard with CPU
overhead. scrypt mentions 5 seconds of work, that would be
unacceptable server overhead for every login.

Any thoughts appreciated,

Paul
From: Datesfat Chicks on
"Paul Johnston" <paul.paj(a)gmail.com> wrote in message
news:e141d99c-0280-407c-9245-9224e4a32ac6(a)j8g2000yqd.googlegroups.com...
> Hi,
>
> I am creating an intranet web application that will authenticate with
> user name and password. Obviously, I want to store the passwords
> hashed. This is only a defence-in-depth mechanism - I'm planning on
> the hashes remaining secret, unless there is a database compromise.
> The threat profile is somewhat different to, say, WPA-PSK.
>
> There are a number of potential algorithms to do this - scrypt,
> pbkdf2, bcrypt, etc. Is there any guide on which is best to use? Or
> are they all largely equal? I don't want to go overboard with CPU
> overhead. scrypt mentions 5 seconds of work, that would be
> unacceptable server overhead for every login.
>
> Any thoughts appreciated,

I think there are three compromise possibilities:

a)The database is compromised.

b)The server software is compromised (root access).

c)The server is physically compromised (someone has physical access).

The most common scheme is never to store passwords (not even encrypted), but
to instead store a cryptographic hash of the password. This means that you
can never supply a user with a lost password--you can only reset the
password to something else.

I'm assuming that you want the passwords to be unrecoverable (which is the
most common scheme, and probably the best practice).

By mixing in some salt, you can make a dictionary attack infeasible. You'll
reduce the problem to brute-force guessing to try to match the hash.

So, the final question would be how to make even brute-force password
guessing impossible. In order to do this, you need to create a situation
where someone who has accomplished (a) can't make the mapping from a
password to the hash stored in the database.

There are two ways to do this:

1)Encrypt the hashes in the database with a key that is hard to obtain. You
might, for example, write an SUID program that tries to determine if the
invoking process is an uncompromised web server, and even then it will only
deliver the key by a pipe or other fairly secure IPC mechanism.

2)Use that same SUID program and deliver some additional salt for hashing
rather than the key (same effect--attacker can't map from password to hash).

(1) and (2) can be broken, but it takes quite a bit of work to
reverse-engineer and break something like that.

If you want to get medieval, you could even have the hashing done by a
remote machine and be rate-limited. That way, if the base machine is
compromised, they can't guess very rapidly unless they can compromise both
machines.

Most web developers just keep a file separate from the database that is used
as additional salt for a hash, and are satisfied with that.

Datesfat

From: Maaartin on
On Jun 8, 8:41 am, Paul Johnston <paul....(a)gmail.com> wrote:
> There are a number of potential algorithms to do this - scrypt,
> pbkdf2, bcrypt, etc. Is there any guide on which is best to use? Or
> are they all largely equal? I don't want to go overboard with CPU
> overhead. scrypt mentions 5 seconds of work, that would be
> unacceptable server overhead for every login.

I'm by far no expert, but I'd prefer scrypt since it's memory hard. If
you can't go for 5 seconds, you can use less iterations while still
requiring a lot of memory, which makes cracking using cheap GPUs or
ASICs quite impossible. I don't know if the other algorithms have
their own advantages (beyond being standardized).
From: Datesfat Chicks on
"Carsten Krueger" <cakruege(a)gmail.com> wrote in message
news:7eybrva607il$.dlg(a)cakruege.my-fqdn.de...
> Am Mon, 7 Jun 2010 23:41:17 -0700 (PDT) schrieb Paul Johnston:
>
>> Is there any guide on which is best to use?
>
> PBKDF2 is industrie standard (has it's own RFC).

If I'm understanding this discussion, there are three different approaches
being discussed:

a)Making the hash expensive to calculate.

b)Using salt to make dictionary attacks infeasible.

c)Using a hidden salt or hidden basis value (that won't be revealed if the
database is compromised because it exists outside the database) so that an
attacker is missing a piece of the information required to calculate the
hash at all (which renders compromise of the database irrelevant because the
hash stored there won't make an attack cheaper than just trying random
passwords).

I think you can actually combine all three approaches without a problem. If
the PBKDF2 algorithm allows very long passwords, you can just append the
"hidden basis value" to the user's password before starting the algorithm.

If the database is compromised (and only the database is compromised), the
attacker won't be able to make the mapping from password to hash at any
cost, which renders compromise of the database irrelevant.

As an example, assume you store the value
"1983649812364981236401230647123656123094601237" outside of the database
(perhaps on another server, perhaps via another mechanism).

If the user's password is "cat", then the password you'd use for input to
the PBKDF2 algorithm is "cat1983649812364981236401230647123656123094601237".

If the database is compromised, the attacker won't have the string
"1983649812364981236401230647123656123094601237", so the attacker can't make
the mapping from "cat" to the hash.

Compromise of the database is then irrelevant.

I've always used (b) and (c), and I'm not claiming that I'm a skilled web
developer.

You've discussed (a) and (b).

(a) is new to me.

But (a), (b), and (c) can be combined I believe.

Datesfat

From: unruh on
On 2010-06-08, Datesfat Chicks <datesfat.chicks(a)gmail.com> wrote:
> "Carsten Krueger" <cakruege(a)gmail.com> wrote in message
> news:7eybrva607il$.dlg(a)cakruege.my-fqdn.de...
>> Am Mon, 7 Jun 2010 23:41:17 -0700 (PDT) schrieb Paul Johnston:
>>
>>> Is there any guide on which is best to use?
>>
>> PBKDF2 is industrie standard (has it's own RFC).
>
> If I'm understanding this discussion, there are three different approaches
> being discussed:
>
> a)Making the hash expensive to calculate.

This is protection against brute force cracking.

>
> b)Using salt to make dictionary attacks infeasible.

This is protection against precomputed dictionary attacks.

>
> c)Using a hidden salt or hidden basis value (that won't be revealed if the
> database is compromised because it exists outside the database) so that an
> attacker is missing a piece of the information required to calculate the
> hash at all (which renders compromise of the database irrelevant because the
> hash stored there won't make an attack cheaper than just trying random
> passwords).

Not sure what this protects against. And it is dangerous. If it is
stored on another machine suddenly this machine becomes useless if the
otehr machine goes down or is disconnected. Not good. If it is on the
machine, it is a "single point of failure" in that someone, somehow
getting ahold of that secret suddenly renders this protection useless.
And since that secret is reused and must last for years, the chances of
that failure grow. Ie, while it does offer some protection it is an
unknown protection ( it could be zero) and should therefor be regarded
as offering no protection at all.
>
> I think you can actually combine all three approaches without a problem. If
> the PBKDF2 algorithm allows very long passwords, you can just append the
> "hidden basis value" to the user's password before starting the algorithm.
>
> If the database is compromised (and only the database is compromised), the
> attacker won't be able to make the mapping from password to hash at any
> cost, which renders compromise of the database irrelevant.
>
> As an example, assume you store the value
> "1983649812364981236401230647123656123094601237" outside of the database
> (perhaps on another server, perhaps via another mechanism).
>
> If the user's password is "cat", then the password you'd use for input to
> the PBKDF2 algorithm is "cat1983649812364981236401230647123656123094601237".
>
> If the database is compromised, the attacker won't have the string
> "1983649812364981236401230647123656123094601237", so the attacker can't make
> the mapping from "cat" to the hash.
>
> Compromise of the database is then irrelevant.

compromise of that "secret" is even more probable than compromise of the
database.

>
> I've always used (b) and (c), and I'm not claiming that I'm a skilled web
> developer.
>
> You've discussed (a) and (b).
>
> (a) is new to me.

It was there already in the old unix des based hash ( 25 encryptions of
the number 0 using the password as the des key-- which was why the
password was limited to 8 ascii characters). That repetition had the
purpose of slowing down repeated attempts (25 was chosen because it
would take a "long time" on the machines in the 80s. The newer MD5 based
hashes do the same thing, with additional time taking shiffling around
of the output of one run to produce the input to the next.

>
> But (a), (b), and (c) can be combined I believe.

While c adds some security, it is really an unkown amount and could be 0.
>
> Datesfat
>