Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (2.78 MB, 385 trang )
The Same-State Problem
This brings us to a serious problem that you ﬁnd on some hardware platforms.
We’re talking here about small embedded computers—something like a door
lock or a remote smart card reader. These typically consist of a small CPU, a
small amount of RAM, nonvolatile memory (e.g., ﬂash) to store the program,
some communication channels, and further task-speciﬁc hardware.
You will notice that a real-time clock is often not included. Adding a realtime clock requires an extra chip, an oscillator crystal, and most importantly, a
battery. Apart from the extra cost, adding a battery complicates the device. You
now have to worry about the battery running out. Batteries can be sensitive to
temperature ﬂuctuations, and the toxic chemicals in some batteries can even
lead to problems with shipping the hardware. For all of these reasons, many
small computers do not have a real-time clock.
Every time such a small computer is booted, it starts in exactly the same state.
It reads the same program from the same nonvolatile memory, initializes the
hardware, and starts operations. As this is a book about cryptography, we will
assume that some kind of cryptographic protocol is used in the communication
with other pieces of the system. But here is the problem: without a clock or
hardware random number generator, the embedded system will always repeat
the exact same behavior. Suppose the attacker waits until the gate computer
needs to open the gate because a truck needs to pass through. She reboots
the gate computer just before the gate needs to open (e.g., by interrupting
the power supply momentarily). After some initialization procedures, the
central system will command the gate computer to open the gate via the
communication channel. The next day, the attacker reboots the gate computer
again, and sends exactly the same messages as were sent the ﬁrst time. As the
gate computer starts in the same state and sees the same inputs, it behaves the
same and opens the gate. This is bad. Note that it doesn’t matter if the gate
computer uses a time synchronization protocol. The protocol messages can be
replayed from yesterday, and the gate computer has no way of detecting this.
The same-state problem is not solved by any protocol.
A real-time clock chip solves this problem. The small embedded computer
can encrypt the current time with a ﬁxed secret key to generate highly random
data. This data can in turn be used as a nonce in a cryptographic protocol. As
the real-time clock never repeats its state, the embedded computer can avoid
falling into the same-state trap.
A hardware random number generator has the same effect. It allows the
embedded computer to behave differently each time it is rebooted.
But if you don’t have a real-time clock or a random number generator, you
have a big problem. Sometimes you can fudge a bit and try to extract randomness from the clock skew between the local clock oscillator and the network
timing or another oscillator, but it is very hard to extract enough entropy from
this within a short time. Taking 10 minutes to reboot an embedded computer
is simply unacceptable.
We’ve seen the same-state problem come up again and again. The upshot
is that the hardware has to change before you can do useful cryptography
on such small computers. This is hard to sell to managers, especially since
the hardware is often already in the ﬁeld and they don’t want to hear that
something cannot be done. But there is no magic security sauce that you can
pour over an existing insecure system to make it secure. If you don’t design
the security into the system from the very start, you almost never get good
There is one more possible solution, though it rarely works in practice.
Sometimes you can keep a reboot counter in the nonvolatile memory. Each
time the CPU reboots, it increments a counter in nonvolatile memory. This
solution is fraught with problems. Some nonvolatile memories can only be
updated a few thousand times, which makes the machine wear out if you keep
updating the counter. Some nonvolatile technologies require an additional
power voltage to be programmable, which is often not available in the ﬁeld.
In some designs, you can only set bits in nonvolatile memory, or wipe all of
the nonvolatile memory. The latter option is not viable, as you’d lose the main
program of the machine. Even if all these problems are overcome, it is very
difﬁcult to modify nonvolatile memory in such a way that the counter always
reliably increases even if the power supply to the machine can be interrupted
at arbitrary points in time. This nonvolatile counter option is only viable in
a minority of the cases we’ve seen. When it is feasible, such a counter could
be used as part of a prng. For example, the counter could be used with CTR
mode and an AES key to generate a stream of pseudorandom bits.
While we’re discussing clocks, we have a few short comments on which time
base to choose. Stay away from local time. Local time is the time we use on our
watches and other clocks. The problem is, local time changes with daylight
saving time and time zone. These changes pose problems: some time values
are repeated each year when clocks are set back an hour in the fall, which
means that the time is no longer unique or monotonic. Some time values are
impossible when clocks are set forward an hour in the spring. Furthermore,
the exact date on which daylight saving time starts and stops is different in
different countries. In some countries, the rules change every few years, and
you don’t want to have to update your software for that. And people who
travel with laptops might change the time on their laptops to the local time,
which just makes these problems worse.
The obvious choice is to use UTC time. This is an international time standard
based on atomic clocks, and is widely used throughout the world. Any single
computer can keep track of the offset of local time with regard to UTC and use
this knowledge in interactions with the user.
There is one problem with UTC: the leap seconds. To keep UTC synchronized
with the Earth’s rotation, there is a leap second once every few years or so. So
far, all leap seconds have been extra seconds; there is a particular minute that
gets 61 seconds. It is also theoretically possible to have a missing second. It all
depends on the rotation of the Earth. The problem for computers is that the
leap seconds are unpredictable. Ignoring leap seconds leads to inaccuracies in
measuring time intervals across a leap second. This is not really a cryptographic
problem, but if you want to make a good clock, you might as well do it right.
All computer software always assumes that each minute has 60 seconds. If
you synchronize directly to a real UTC clock, the insertion of a leap second can
lead to problems. Most likely this results in your internal clock repeating itself
for one second. It is a minor problem, but again, it destroys the uniqueness
and monotonicity of time values.
For most applications, the exact synchronization of the clock is less
important than the monotonicity and uniqueness of the time stamps. As
long as you make sure the clock never jumps backwards at a leap second, it
doesn’t matter how you solve this problem.
Unfortunately, we have no ideal solution for you. Creating a reliable clock is
very tricky, especially in a cryptographic setting where you assume there are
malicious attackers. The best solution depends on your local situation. Our
recommendations, therefore, are to be aware there are potential security issues
associated with the use of a clock, minimize reliance on the clock whenever
possible, and be cautious. And again, the most important thing is generally
the monotonicity and uniqueness of the time stamps.
Exercise 16.1 Some computers use NTP at boot, or at regular intervals. Turn
off NTP for one week on your computer. Write a program that at regular
intervals (at least once every two hours) records both the true time and the
time reported by your computer. Let t0 be the initial true time at the start of
your experiment. For each time measurement pair, plot the true time minus t0
on the horizontal axis of a graph and plot your computer’s time minus true
time on the vertical axis. How different is your computer’s clock from true
time after one week? Does your graph tell you anything else?
Exercise 16.2 Repeat exercise 16.1, but this time for a collection of ﬁve
Exercise 16.3 Find a new product or system that uses (or should use) a clock.
This might be the same product or system you analyzed for Exercise 1.8. Conduct a security review of that product or system as described in Section 1.12,
this time focusing on the security and privacy issues surrounding the clock.
At last we turn to key management. This is, without a doubt, the most difﬁcult
issue in cryptographic systems, which is why we left it to near the end. We’ve
discussed how to encrypt and authenticate data, and how to negotiate a shared
secret key between two participants. Now we need to ﬁnd a way for Alice
and Bob to recognize each other over the Internet. As you will see, this gets
very complex very quickly. Key management is especially difﬁcult because
it involves people instead of mathematics, and people are much harder to
understand and predict. Key management is in many ways a capstone to all
we have discussed so far. Much of the beneﬁt of cryptography is defeated if
key management is done poorly.
Before we start, let us make one thing clear. We talk only about the
cryptographic aspects of key management, not the organizational aspects. The
organizational aspects include things like a policy covering whom to issue keys
to, which keys get access to which resources, how to verify the identity of the
people who get keys, policies on the security of the stored keys, mechanisms
for verifying that these policies are being adhered to, etc. Every organization
will implement these differently, depending on their requirements and their
existing organizational infrastructure. We focus only on parts that directly
affect the cryptographic system.
One way to handle key management is to have a trusted entity to hand out
all the keys. We’ll call this entity the key server.
The basic idea is simple. We assume that everybody sets up a shared secret
key with the key server. For example, Alice sets up a key KA that is known
only to her and to the key server. Bob sets up a key KB that is known only to
him and to the key server. Other parties set up keys in the same fashion.
Now suppose Alice wants to communicate with Bob. She has no key she can
use to communicate with Bob, but she can communicate securely with the key
server. The key server, in turn, can communicate securely with Bob. We could
simply send all the trafﬁc to the key server and let the key server act as a giant
post ofﬁce. But that is a bit hard on the key server, as it would have to handle
enormous amounts of trafﬁc. A better solution is to let the key server set up a
key KAB that is shared by Alice and Bob.
This is the basic idea behind Kerberos, a widely used key management system
. Kerberos is based on the Needham-Schroeder protocol .
At a very basic level, here is how it works. When Alice wants to talk to Bob,
she ﬁrst contacts the key server. The key server sends Alice a new secret key
KAB plus the key KAB encrypted with Bob’s key KB . Both these messages are
encrypted with KA , so only Alice can read them. Alice sends the message that
is encrypted with Bob’s key, called the ticket, to Bob. Bob decrypts it and gets
KAB , which is now a session key known only to Alice and Bob—and to the key
server, of course.
One of the features of Kerberos is that the key server, called the KDC in
Kerberos terminology, does not have to update its state very often. Of course,
the key server has to remember the key that it shares with each user. But when
Alice asks the KDC to set up a key between her and Bob, the KDC performs
the function and then forgets all about it. It does not keep track of which keys
between users have been set up. This is a nice property because it allows a
heavily loaded key server to be distributed over several machines in a simple
manner. As there is no state to be updated, Alice can talk to one copy of the
key server one moment and to another copy the next moment.
It turns out that the cryptographic protocols needed for a Kerberos-style
system are very complicated. Initially, designing such protocols looks quite
easy to do, but even experienced cryptographers have published proposals,
only to have them broken later on. The ﬂaws that creep in are very subtle.
We’re not going to explain these protocols here; they are too dangerous to
experiment with and modify by hand. Even we shy away from designing this
type of protocol anew. If you want to use a protocol of this sort, use the latest
version of Kerberos. Kerberos has been around for quite a while, and many
competent people have looked at it.
Sometimes it is not possible to use Kerberos. The protocol is far from simple,
and it imposes some restrictions. Servers have to memorize all tickets that they
have accepted, and every participant needs a reliable clock. There are several
situations in which these requirements cannot be met. Further, we ﬁnd it more
informative to study a simpler design.
We can create a simpler and more robust solution if we don’t put so much
emphasis on efﬁciency. It turns out to be especially useful to allow the key
server to maintain state. Modern computers are far more powerful than they
were in the days when Kerberos was ﬁrst designed, and they should not have
any trouble maintaining state for tens of thousands of participants. Even a very
large system with 100,000 participants is not a problem: if each participant
requires a 1 kilobyte state in the key server, storing all states requires only 100
megabytes of memory. The key server still needs to be fast enough to set up
all the requested keys, but that too is much less of a problem with modern,
We will only discuss the situation in which there is a single key server.
There are techniques that you can use to distribute the key server state over
several computers, but we won’t go into the details, because you really don’t
want to have a key server for tens of thousands of participants; it’s too risky.
The danger of large key servers is that all the keys are in a single place. That
makes the key server a very attractive target for attack. The key server must
also be online at all times, which means an attacker can always communicate
with the key server at will. The current state of the art does not protect
computers from network attacks very well, and putting all your keys in a
single place is an invitation to disaster. For smaller systems, the total ‘‘value’’
of the keys kept by the key server is smaller, so this threat is reduced.1 In
the next few chapters we will explore a solution to the key management
system that is better suited to very large systems. We will restrict our discussion of key servers to fairly small systems—up to a few thousand participants or so.
don’t like to leave any unaddressed threat in the system, but in key management, you
always end up with a compromise solution.
17.3.1 Secure Connection
Here is a brief description of a simpler solution. First, we assume that Alice
and the key server share a key KA . Instead of using this key directly, they use
it to run a key negotiation protocol, like the ones we discussed in Chapter 14.
(If KA is a password, you’d really prefer to use one of the protocols suitable
for low-entropy passwords that we discussed in Section 14.12, assuming the
patent issues are not a problem for you.) The key negotiation protocol sets up
a fresh key KA between the key server and Alice. All other participants also
perform the same protocol with the key server, and they all set up fresh keys.
Alice and the key server use KA to create a secure communication channel (see
Chapter 7 for details). Using the secure channel, Alice and the key server can
communicate securely. Conﬁdentiality, authentication, and replay protection
are all provided by the secure channel. All further communications happen
over this secure channel. All other participants create a similar secure channel
with the key server.
17.3.2 Setting Up a Key
It is now much easier to design a protocol that sets up a key between Alice
and Bob. We only need to consider the case where messages get lost, delayed,
or deleted by the attacker, because the secure channel protects us from all
other types of manipulation. The protocol can now be something fairly simple.
Alice asks the key server to set up a key between her and Bob. The key server
responds by sending a new key KAB to both Alice and Bob. The key server
can even send the message to Bob through Alice, so that it does not need to
communicate with Bob directly. If this happens, Alice simply becomes the
equivalent of a network router transiting a secure channel between the key
server and Bob.
This does pose one limitation on the system: Bob must run the key negotiation protocol with the key server before Alice asks the key server to set up a
shared key with Bob. Whether this turns out to be a problem depends on the
exact circumstances, as do the possible solutions to this limitation.
Like all keys, the KA key must have a limited lifetime. This is easy to arrange,
as Alice can always rerun the key negotiation protocol (using the original key
KA for authentication) to set up a fresh KA key. A key lifetime of a few hours
seems reasonable for most situations.
Because we can always rekey, the key server does not have to store the secure
channel state in a reliable manner. Suppose the key server crashes and loses
all state information. As long as it remembers KA (and the corresponding keys
for the other participants), there is no problem. All we have to do to recover is
run the key negotiation protocol between the key server and every participant
again. So although the key server is not stateless, it does not have to modify its
long-term state—the part that is stored on nonvolatile media—when running
17.3.4 Other Properties
Perhaps our solution is not simpler than Kerberos from an implementation
point of view, but it is simpler from a conceptual point of view. The secure
channel makes it much easier to oversee the possible lines of attack against
the protocol. Using the key negotiation protocol and the secure channel we
already designed is a good example of how modularization can help in the
design of cryptographic protocols.
Using the key negotiation protocol to set up the secure channel has another
advantage: we get forward secrecy. If Alice’s key KA is compromised today,
her old secure channel keys KA are not revealed, and therefore all her old
communications are still secure.
In the earlier parts of the book, we gave a detailed example design of the
cryptographic function we discussed. We won’t do that here, nor will we for
the rest of the book. The cryptography is fairly straightforward, and we could
certainly have described a key server system, but it would not be very useful.
Designing key management systems is more a problem of collecting a suitable
set of requirements for the particular application and getting the user interface
right than a problem of cryptography. To be able to explain the design choices
for a concrete example here, we would have to invent and document the entire
surrounding social and organizational structure, the threat environment, and
the application that needs the key management.
What to Choose
If you want to implement a central key server, you should use Kerberos if
possible. It is widely available and widely used.
In those situations where Kerberos is not suitable, you will have to design
and build something like the solution we described, but that will be a major
operation. For the most common type of cryptographic applications we have
seen, you should count on spending as much time on the key server system as
you did on the entire application. Our discussion here should help guide your
Exercise 17.1 For the protocol in Section 17.3, what is a reasonable lifetime
to use for the keys KA ? Why? What bad things could happen if the lifetime is
longer? What bad things could happen if the lifetime is shorter?
Exercise 17.2 For the protocol in Section 17.3, how might an attacker be able
to learn KA before it times out? What bad things would the attacker be able to
do with that knowledge? What bad things would the attacker not be able to
do with that knowledge?
Exercise 17.3 For the protocol in Section 17.3, how might an attacker be able
to learn KA after it times out? What bad things would the attacker be able to do
with that knowledge? What bad things would the attacker not be able to do
with that knowledge?
Exercise 17.4 For the protocol in Section 17.3, consider an attacker who intercepts all communications. Can the attacker retroactively read data between
Alice and Bob if KA and KB are both later exposed?
Exercise 17.5 For the protocol in Section 17.3, could an attacker gain any
advantage in breaking the protocol by forcibly rebooting the key server?
Exercise 17.6 For the protocol in Section 17.3, could an attacker mount a
denial-of-service attack against two parties wishing to communicate, and if so,
Exercise 17.7 For the protocol in Section 17.3, are there policy or legal risks
with having the key server generate KAB ? Are there things Alice and Bob would
not say in a situation where the key server generates KAB that they would say
if the key were known only to them?
The Dream of PKI
In this chapter we will give the standard presentation of what a PKI is, and
how it solves the key management problem. It is important to understand
this ﬁrst. In the next chapter we’ll talk about the challenges with PKIs in
practice, but for this chapter we’ll visit the perfect world where a PKI solves
all your problems.
A Very Short PKI Overview
A PKI is a Public-Key Infrastructure. It is an infrastructure that allows you to
recognize which public key belongs to whom. The classical description is as
There is a central authority that is called the Certiﬁcate Authority, or CA
for short. The CA has a public/private key pair (e.g., an RSA key pair) and
publishes the public key. We will assume that everybody knows the CA’s
public key. As this key remains the same over long periods of time, this is easy
To join the PKI, Alice generates her own public/private key pair. She keeps
the private key secret, and takes the public key PKA to the CA and says: ‘‘Hi,
I’m Alice and PKA is my public key.’’ The CA veriﬁes that Alice is who she
says she is and then signs a digital statement that states something like ‘‘Key
PKA belongs to Alice.’’ This signed statement is called the certiﬁcate. It certiﬁes
that the key belongs to Alice.
If Alice now wants to communicate with Bob, she can send him her public
key and the certiﬁcate. Bob has the CA’s public key, so he can verify the