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


[email protected] (Norman Hardy) writes:

>At 09:51 1994/07/26 -0400, Russell Nelson wrote:
>>Why not generate a random number, checksum it, and sign it using a
>>public key?  Or is that overkill?
>Seems good. But to thwart replay of the signed message the garage unit must
>never accept the same signed number twice. How about the car unit signing
>successive numbers. The garage unit would remember the last number that it
>accepted and only accept signed numbers larger than that. Garbled
>transmissions would then cause no problems. They would be fixed by yet new
>transmissions, just as with current units.

As Eric Hughes points out (a couple of messages after these), you don't
need public-key signatures for this; any secret key cipher or hash function
will do, since the  base and remote trust each other unconditionally
(at least for garage doors; nuclear weapons may be a different story).

Both base and remote need to store a shared key and a counter; the remote 
needs a transmitter and the base needs a receiver.  To authenticate
itself, the remote sends {counter, hash(key,counter)} and then increments
its counter.  The base calculates the hash for the received counter value,
verifies that it matches the received hash value, verifies that the counter
increases the stored counter value, stores the new value,  and opens
the door.  A practical system system also probably include some mechanism
for rekeying and for zeroizing the counters.

There is no need for public key cryptography, two way communication (except
for key setup), synchronized clocks, or extensive storage at either side.

This protocol as described is very simple, almost trivial; given the right
constraints it follows almost directly from the problem.  I mention
it because very small variations and poorly chosen parameters render
it vulnerable to several classic protocol failures.

First, observe that this system has a work factor to break of no more than
the SMALLER of the secret hash key and the size of the hash output.  Clearly,
a single {counter, hash(key,counter)} message contains enough information to
permit an conventional exhaustive search for key.  If the hash space is
too small (say, 16 bits or so), the adversary can select an unused counter
value and probe the receiver with random hash values until the door opens.
Worse, if the bad guy selects a counter value that is much larger than the 
remote's counter value, it has the added bonus of denial-of-service to the
real user.

Also, note that the order of operation on the receiver's part is critical.
If the received counter value is stored BEFORE the hash is received, we
are also vulnerable to denial-of-service (but at least not false

Finally, there is the "man in the middle" attack, in which the bad guy
intercepts a message intended for but never received by the base,
records it, and plays it back later (but before the real owner returns
to increment the counter again).  A likely scenario involves pushing the
button twice on return home, but where only the first message is received by
the base. One way to deal with this is to encourage frequent resyncs between
the base and remote; for example, the remote, when in the garage, could send
periodic "null" commands that increment the counters without actually
opening the door.  (Of course, you'd need to make sure that these messages
themselves cannot be used to construct spoofed open-door messages.)  Basing
the counter in part on a real-time clock would also help here, but again,
this complicates the protocol greatly and increases the opportunities for
both denial-of-service (if the clocks get too far out of sync) and false
authentication (if the clocks get reset - say at daylight savings time...)

My point is not that this is a particularly hard problem, only that
even simple cryptographic protocols can have serious bugs.