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

RE: a challenge



> You're right - since you can't decrypt, you can't check expiration
> (easily). Although you could potentially run a loop to check against a
> range of values; depending on how precise you need it to be. 
> For example, if tokens can expire on a 15-minute granularity then it's not

> too much of a problem to simply check each of them manually.
> 
> The typical way to do that is:
> 
> if (crypt($plain, $crypted) eq $crypted) {
> 	you guessed right.
> }

Ick...

If we can loosen the 4-16 byte constraint a bit (why 16 bytes??? Why not
32?)
we can make much better headway. To have a truly secure token you need to do
something similar to how kerb5 works, although we can probably avoid a lot
of that work. 

Let P be a secret of arbitrary length that authenticates a user. Let p be a
secrety of arbitrary length that authenticates the token service. Let MD5 be
the MD5 hash function. Let T be the current time stamp in seconds since the
epoch. Let . denote the concatention operation in string form.

Let S=MD5(P . p . T) and define a token t to be of the form t=[S . T]

Verification of the token is done at the server, by the user. Since only the
server knows p, the user cannot forge a token without breaking MD5. Since
the user has to supply P, he cannot hijack a user's token from the network
without knowing P for that user. If the user modifies his token to be 

t'=[S . T']

then the token is invalid. The user cannot compute a corresponding S' as he
doesn't know p and cannot create a token of his own.

Now, the strength of such a scheme relies entirely on the hashing algorithm.
Several enhancements could also be made by requiring that P and p must
expire and a number of other features. Go read about kerberos for the
details on really secure tokens.

As for meeting the 4-16 character barrier, you could (though I do not
recommend) taking the high 7 bytes of the MD5 hash, redistributing them over
8 bytes so that they are 7 bit encoded and use a long long for a timestamp.
That'd give you exactly 16 bytes. However I have no idea what the
cryptographic impact of doing that to MD5 is. It is highly likely that it
becomes susceptible to birthday attacks and the like. 

If you can loosen the restraints to 8bit data and 20 bytes, you can use a
full MD5 hash and a long to store the time. You can avoid roll-over in 2038
by using an unsigned long.

Ideally, you'd use a millisecond resolution timer and SSHA instead of MD5.
But that's a nitpick.

--jeh




Reply to: