help-gsasl
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: SCRAM methods


From: Simon Josefsson
Subject: Re: SCRAM methods
Date: Mon, 06 Jan 2020 12:06:58 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux)

Jeremy Harris <address@hidden> writes:

> On 03/01/2020 15:28, Jeremy Harris wrote:
>> On 03/01/2020 14:40, Simon Josefsson wrote:
>>> Clients should store the ClientKey:
>>>
>>> ClientKey       := HMAC(SaltedPassword, "Client Key")
>
> As far as I can tell, the client needs to additionally
> store the ServerKey - otherwise the ClientKey is not enough
> (it needs the salted-password in order to calculate the
> ServerKey, to calculate the ServerSignature for comparison
> with what comes over the wire, to validate the server).

Right.  I'll update the documentation to make these subtle points more
clear once the support is added.  Below are some of my thoughts on this,
in case anyone wants follow or challenge them.

To summarize, I believe the client will need to know one of these
credentials (together with username, host etc):

1) the password

The worst -- an attacker stealing it will be able to impersonate both
clients and servers, and use the password against other services.

2) SaltedPassword (will only work for a particular salt/itercnt.
                   The client doesn't need to store salt/itercnt but
                   there will be server-side failure if they differed,
                   so in practice the client will need to store
                   salt/itercnt too to provide good UX)

Somewhat better -- the attacker can't directly use this to attack other
services with the same password (without recovering the password which
is possible through brute-force testing), but can still impersonate both
client and server (for that particular salt/itercnt).  The attacker can
impersonate clients/servers in some hypothetical non-SCRAM protocol that
uses PBKDF2 databases with the same salt/itercnt, without recovering the
password.

3) ClientKey and ServerKey (for a specific salt/itercnt.
                            Same situation with salt/itercnt as in 2)

Somewhat better -- the attacker can't directly use this to attack other
services with the same password (without recovering the password which
is possible through brute-force testing), but can still impersonate both
client and server (for that particular salt/itercnt).  The attacker
cannot impersonate clients/servers in some hyphothetical non-SCRAM
protocol that uses PBKDF2 databases with the same salt/itercnt, without
recovering the password.

The difference between 2 and 3 are really minor on the client side.  I
don't think the added complexity motivate advantage -- the attack
assumes that another unrelated server uses the same salt/itercnt, which
sounds like a weird case.

My conclusion is that clients should store SaltedPassword/Salt/Itercnt.
I'm not sure adding support for CLIENTKEY/SERVERKEY is really worth the
trouble.  Cyrus SASL only seems to support raw clear-text passwords in
the client.

Am I missing something?

On the server, it has to know one of these cases:

1) the password

The worst -- an attacker stealing it can impersonate both client and
server and use it against other services.

2) SaltedPassword, salt, itercnt

Somewhat better -- the attacker who steal them can impersonate both
client and server (for the particular salt/itercnt), and use it in some
hyphothetical non-SCRAM protocol that re-use the same database and uses
PBKDF2.

3) StoredKey, ServerKey, salt itercnt

Slightly better? -- the attacker who steal them can impersonate a server
(for the particular salt/itercnt) but to impersonate the client the
attacker also need to see a recording of one authentication, or be part
of one authentication with the client -- this allows it to recover the
ClientKey from the ClientProof sent by the client.  The attacker cannot
impersonate a client/server in some hyphothetical non-SCRAM protocol
that uses PBKDF2 databases with the same salt/itercnt without password
recovery (e.g., brute-force).

So the only difference between 2) and 3) on the server-side appears to
be that the attacker needs to see, or be part of, one authentication in
order to do everything it could have done in 2).

I wonder if the advantage with 3) is really worth the added complexity?

What practical scenario does 3) really defend against compared to 2)?  A
passive attacker who steals the credential presumably wants to use the
stolen information for something.  If it is to impersonate the server it
can do so directly.  If it is to impersonate the client, it is only
slightly harder than with 2). It will have to look at a transcript of
one authentication, or impersonate the server once.  If it is to use it
against other services, it can use the data in 3) just like in 2) to
brute-force it and recove the password.

Am I missing something?

Compatibility with other SASL libraries is also a factor: I see that
Cyrus SASL supports storing b64-encoded ServerKey/StoredKey on the
server side.  So we should support that too.  And for simplicity, it is
probably better for Exim to support storing them, so there is only one
set of data that needs to be stored regardless of implementation.  Cyrus
SASL does not support using the SaltedPassword it seems.

So I think what we need is (nothing new since earlier emails):

1) SCRAM server retrieve ServerKey/StoredKey and use it.
2) APIs to compute SaltedPassword, ServerKey/StoredKey.

>>> Servers should store StoredKey and the ServerKey:
>>>
>>>      StoredKey       := H(ClientKey)
>>>      ServerKey       := HMAC(SaltedPassword, "Server Key")
>> 
>> ... along with salt, itercnt?
>
> I have this coded (both libgsasl and exim) and apparently operational.
> Please say if you want a copy of my hacking.

Yes please!

I thought a bit more and will implement a 'gsasl --mkpasswd' parameter
to prepare hex/b64 encoded PBKDF2, SCRAM-StoredKey, SCRAM-ServerKey,
salt, etc outputs.  This could be used to create content suitable for
exim passwd files.  I'm sure other tools could supply this too
(including some new exim tool) but it is useful to have it in gsasl.  I
realized some improvements to DIGEST-MD5 are possible in this area too
(client: use a hashed password; server: extract a hashed password),
although I'm not sure if it is worth doing anything with DIGEST-MD5 at
this point.

/Simon

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]