Improving POP3/IMAP CRAM authentication

39 views
Skip to first unread message

Solar Designer

unread,
Mar 7, 1999, 3:00:00 AM3/7/99
to
I've been reading the relatively recent RFCs on POP3 and IMAP protocol
extensions designed to support more secure authentication methods. What
I was looking for is a simple method (no public key crypto) that would
still always be better than plaintext authentication.

Unfortunately, none of the suggested methods seemed to achieve that; a
server compromise (even for a minute) would result in a disaster worse
than with plaintext authentication and a good password hashing scheme.

After a bit of thinking I came up with the approach I'm including below.
The reasons I'm posting it are -- (1) to make sure I am not missing some
obvious (or not very obvious) attack, and (2) to find out whether I have
invented the wheel (and there's already a standard C/R protocol that
achieves all the same goals), or not.

stored at the server:
hash = H(H(password))
the client needs to know:
H(password) (or the password, if entered manually each time)
session:
S: challenge = unique()
C: response = H(H(H(password)), challenge) ^ H(password)
S: if (H(H(hash, challenge) ^ response) == hash) auth_ok
attacks, when the server's security isn't compromised:
obvious: brute-force attacking sniffed challenge/response pairs
attacks, after the server gets compromised:
possible to derive H(password) from sniffed traffic
comparison to other simple authentication algorithms:
never worse than plaintext: sniffing is always required
both APOP and CRAM _are_ sometimes worse than plaintext
better than APOP: doesn't store plaintexts at the server
better than CRAM: doesn't store immediately usable auth tokens
like with APOP/CRAM, the server needn't write to its database
references:
APOP: RFC 1939
CRAM: RFC 2195, 2104
performance:
only the inner hash should preferably be slow (iterated)
the server's performance is not affected by the inner hash

--
/sd

Alan DeKok

unread,
Mar 8, 1999, 3:00:00 AM3/8/99
to
In article <7btpnk$oe9$1...@prince.dataforce.net>,
Solar Designer <so...@cannabis.dataforce.net> wrote:

> I've been reading the relatively recent RFCs on POP3 and IMAP protocol
> extensions designed to support more secure authentication methods. What
> I was looking for is a simple method (no public key crypto) that would
> still always be better than plaintext authentication.

They do exist. The problem is finding them, and telling people
about them.

> After a bit of thinking I came up with the approach I'm including below.
> The reasons I'm posting it are -- (1) to make sure I am not missing some
> obvious (or not very obvious) attack, and (2) to find out whether I have
> invented the wheel (and there's already a standard C/R protocol that
> achieves all the same goals), or not.

There's almost always something similar in the literature. One of
the ones I like is:

http://www.sevenlocks.com/papers/authent/bird1.txt

But it's may be too complicated for POP3 && IMAP.

> stored at the server:
> hash = H(H(password))
> the client needs to know:
> H(password) (or the password, if entered manually each time)
> session:
> S: challenge = unique()
> C: response = H(H(H(password)), challenge) ^ H(password)
> S: if (H(H(hash, challenge) ^ response) == hash) auth_ok

The hash at the server is plaintext equivalent: use salts.

My suggestion:

S = Salt
P = password
R = random number

Stored by the server as the 'password' (ala 'crypt' and /etc/passwd)

H_S = H(S+P)

Sent by the server to the client on a connection:

S,R

Calculated by the client, and sent to the server:

H(R + H(R + H(S + P)))

Calculated by the server:

H(R + H(R + H_S) = H(R + H(R + H(S + P))) from the client.


However, this protocol has problems, most notably it's vulnerable to
spoofing by a man in the middle. What would be better is the
following, which is lifted from Figure 27 of the paper, with
modifications for this situation.

Client Server

N1
(1) ----------------------->

S, N2, MAC(N1, N2, N1 XOR B)
(2) <-----------------------

MAC(N1, N2)
(3) ----------------------->


where MAC(M) = H(H_S + H(H_S + M)), with S and H_S as above, N1 and
N2 are 64-bit random numbers, and B is the IP address of the server.

Using H_S protects from server comprimise, hopefully at least as
much as crypt() now does. Using the 3-pass non-symmetric protocol
protects agains man in the middle attacks, and others.

See 'Shneier, B., "Applied Cryptography, 2nd Ed."', p. 458, and RFC
2107 for information on MAC's.

Alan DeKok.

David P Jablon

unread,
Mar 9, 1999, 3:00:00 AM3/9/99
to
In article <7c1nba$huj$1...@garm.localnet>, Alan DeKok wrote:

>In article <7btpnk$oe9$1...@prince.dataforce.net>, Solar Designer wrote:
>
>> I've been reading the relatively recent RFCs on POP3 and IMAP protocol
>> extensions designed to support more secure authentication methods. What
>> I was looking for is a simple method (no public key crypto) that would
>> still always be better than plaintext authentication.
>
> They do exist. The problem is finding them, and telling people
> about them.

The strongest methods use exponential arithmetic, but don't
require any certificates or any stored keys for the user.
Many of them (SPEKE, EKE, OKE, SRP, ...) are described in papers at:
<http://world.std.com/~dpj/links.html>

PK crypto in some form is needed to prevent brute-force
attacks by eavesdroppers and middlemen, when the key is based
on a human-chosen password.

------------------------------------------------------
David Jablon
d...@world.std.com
<http://world.std.com/~dpj/>

Solar Designer

unread,
Mar 10, 1999, 3:00:00 AM3/10/99
to
In article <7c1nba$huj$1...@garm.localnet>, Alan DeKok wrote:
> > I've been reading the relatively recent RFCs on POP3 and IMAP protocol
> > extensions designed to support more secure authentication methods. What
> > I was looking for is a simple method (no public key crypto) that would
> > still always be better than plaintext authentication.
>
> They do exist. The problem is finding them, and telling people
> about them.

[...]

> There's almost always something similar in the literature. One of
> the ones I like is:
>
> http://www.sevenlocks.com/papers/authent/bird1.txt

Thanks, I'll read this later.

> > stored at the server:
> > hash = H(H(password))
> > the client needs to know:
> > H(password) (or the password, if entered manually each time)
> > session:
> > S: challenge = unique()
> > C: response = H(H(H(password)), challenge) ^ H(password)
> > S: if (H(H(hash, challenge) ^ response) == hash) auth_ok
>
> The hash at the server is plaintext equivalent: use salts.

Why is it plaintext equivalent? I am storing H(H(P)), while H(P)
is needed to authenticate. The XOR trick I am doing is somewhat
similar to encrypting H(P) with a stream cipher for transmission.

The worst problem (mentioned in my original post) I see with this
approach, is the fact that after a server compromise we're back to
the level of security we would have with plaintext authentication;
just like I've said, other C/R protocols proposed for POP3 or IMAP
don't offer even that.

Speaking of salts, I was going to add them in a real implementation,
as well as a variable iteration count for the inner hash. There're
still a few issues with probing for valid usernames, but I think I
know of a way to get around those.

> My suggestion:
>
> S = Salt
> P = password
> R = random number
>
> Stored by the server as the 'password' (ala 'crypt' and /etc/passwd)
>
> H_S = H(S+P)
>
> Sent by the server to the client on a connection:
>
> S,R
>
> Calculated by the client, and sent to the server:
>
> H(R + H(R + H(S + P)))
>
> Calculated by the server:
>
> H(R + H(R + H_S) = H(R + H(R + H(S + P))) from the client.

I don't see how this is safe from a server compromise: you're storing
H(S+P), and this is the only thing needed for a client to authenticate.

Perhaps when saying about being at least as secure as plaintext
authentication, even after a server compromise, we mean different
things. What I mean is:

1. Passwords are securely hashed on the server. That is, their
hashes aren't easier to brute-force than crypt(3) hashes would be.

2. It is impossible to authenticate with just the stolen hashes.

3. Unfortunately, it may be possible to get a suitable authentication
token for this protocol only (not the plaintext password, which might
be used on another system as well) -- with sniffing -- after the
attacker got access to the server's hashes -- but, just like I've
said, this is no worse than plaintext authentication and crypt(3).

Now, after thinking a bit more and looking up the archives of this
newsgroup of three months ago, I think there's a way to solve even
the remaining problem (plaintext authentication level of security
only, after a server compromise).

Bryan Olson has then pointed out a nice OTP-like C/R algorithm. If
used as described, it would have the following main limitation: the
server would need to update the password database (and probably sync
the write) at each authentication. This is often not acceptable.

However, this algorithm seems excellent for recovering after a server
compromise with my protocol; simply make the inner hash iterated a
variable number of times (which I was going to do anyway, despite
having to solve the username probing issues then), and decrease the
number of iterations when recovering after a compromise. :-)

> See 'Shneier, B., "Applied Cryptography, 2nd Ed."', p. 458, and RFC
> 2107 for information on MAC's.

You probably mean RFC 2104.

--
/sd

Reply all
Reply to author
Forward
0 new messages