Managing a separate shared key for every pair of participants becomes cumbersome in a company with thousands of employees and hundreds of servers. Instead, each participant can hold one key shared with a trusted server acting as a trusted third party.
Both participants trust this server to store their keys securely. When two parties want to communicate, the server creates a session key for them and delivers a copy to each, encrypted under that party’s long-term key.
This arrangement cuts the number of long-term keys from roughly \(n^2/2\) to \(n\). It also puts all of the trust in one place. The trusted server is known as a key distribution center (KDC), and the protocols in this family define the messages it exchanges with each party.
Security Protocol Notation
Protocols are written in a compact notation that shows who sends what to whom. Unfortunately, the syntax differs from the functional notation we saw when describing encryption, where we used \(E_K(M)\) to say message \(M\) is encrypted with a key \(K\). The conventions used here are standard:
-
Alice (\(A\)) and Bob (\(B\)) are the parties who want to communicate. Trent (\(T\)) is the trusted third party.
-
\(A \rightarrow B: X\) means that Alice sends message \(X\) to Bob.
-
\(K_A\) is a long-term key shared by Alice and Trent, and \(K_B\) is a long-term key shared by Bob and Trent. \(K_{AB}\) is a session key for Alice and Bob.
-
\(\lbrace M \rbrace_K\) is message \(M\) encrypted with key \(K\), in a way that also detects tampering.
-
\(X \parallel Y\) is the concatenation of \(X\) and \(Y\). A comma-separated list, such as \(A, B, r_1\), also means that the fields are sent together in one message.
-
\(r_1\) and \(r_2\) are nonces, and \(t\) is a timestamp.
-
A ticket is a credential that a trusted third party creates for one party to present to another. It is encrypted with a key shared by the trusted third party and the recipient, so the party presenting it can forward it but cannot read or change its contents.
A protocol written in this notation lists the messages the parties exchange, but not the checks each recipient performs. Each message has to be read together with those checks. For example, \(T \rightarrow A: \lbrace r_1, K_{AB} \rbrace_{K_A}\) is useful only if Alice compares \(r_1\) with the nonce she sent and rejects a mismatch. Successful decryption alone does not establish that a reply belongs to the current request.
A Basic Key Distribution Protocol
Consider the most direct design. Alice asks Trent for a key to talk to Bob. Trent generates \(K_{AB}\) and sends Alice two copies of it: one encrypted for her, and a ticket encrypted for Bob. Alice forwards the ticket. In protocol notation, the exchange is:
-
\(A \rightarrow T: A, B\)
-
\(T \rightarrow A: \lbrace K_{AB} \rbrace_{K_A}, \lbrace K_{AB}, A \rbrace_{K_B}\)
-
\(A \rightarrow B: \lbrace K_{AB}, A \rbrace_{K_B}\)
Alice cannot read Bob’s ticket. Bob can decrypt it and see that Trent issued the key for use with Alice, but he cannot tell when it was issued.
An adversary who recorded an earlier run can replay message 3 to Bob at any time. Bob decrypts a valid ticket and accepts an old key. If that key was ever compromised, through a memory dump or a careless log file, the adversary can now impersonate Alice. Even if the key was not compromised, the adversary can push Bob back onto a key that Alice has since discarded. The same weakness affects Alice, since a replayed message 2 would give her an old key as though it were new.
The Needham-Schroeder Protocol
Roger Needham and Michael Schroeder published a symmetric-key authentication protocol in 1978. It adds nonces to the basic protocol, along with a final exchange between Alice and Bob:
-
\(A \rightarrow T: A, B, r_1\)
-
\(T \rightarrow A: \lbrace r_1, B, K_{AB}, \lbrace K_{AB}, A \rbrace_{K_B} \rbrace_{K_A}\)
-
\(A \rightarrow B: \lbrace K_{AB}, A \rbrace_{K_B}\)
-
\(B \rightarrow A: \lbrace r_2 \rbrace_{K_{AB}}\)
-
\(A \rightarrow B: \lbrace r_2 - 1 \rbrace_{K_{AB}}\)
The nonce \(r_1\) in message 1 comes back inside message 2, encrypted under \(K_A\), which Alice shares only with Trent. Alice checks that the nonce matches her request. A reply recorded from an earlier run contains an earlier nonce and is rejected.
Bob’s name is inside message 2 as well. Without it, an adversary could change the \(B\) in Alice’s plaintext request to the name of another party, and Alice would receive a key she believes is shared with Bob but that is actually shared with someone else. With it, Alice checks that the key is for the party she asked about.
The ticket \(\lbrace K_{AB}, A \rbrace_{K_B}\) is sealed inside Alice’s part of message 2. Alice cannot read it or alter it, and she forwards it to Bob in message 3.
Messages 4 and 5 are a handshake. Bob sends a nonce encrypted under the new key, and Alice returns a value derived from it. The subtraction ensures that Alice’s reply differs from Bob’s message, so an adversary cannot send message 4 back to Bob. The handshake shows Bob that someone holding \(K_{AB}\) is taking part right now.
The Denning-Sacco Attack
In 1981, three years after the protocol appeared, Dorothy Denning and Giovanni Sacco showed that it had a flaw.
Suppose an adversary recorded a run of the protocol and later recovered the session key from that run. The adversary replays the old message 3 to Bob. Bob decrypts the ticket and finds a valid key and Alice’s name. He sends message 4, encrypted with that key. The adversary knows the key, decrypts Bob’s nonce, and sends back a correct message 5. Bob now believes he is talking to Alice under a fresh key. The adversary can repeat this indefinitely, long after Alice has forgotten the key.
Alice’s nonce establishes that Trent’s reply is fresh for Alice. Bob’s nonce establishes that someone who knows \(K_{AB}\) is responding now. Neither tells Bob that the key itself is new. The attack exploits that distinction between a fresh response and a fresh key.
Timestamps in the Ticket
Denning and Sacco proposed a fix that gives Bob his own evidence. Trent includes a timestamp in the ticket:
-
\(A \rightarrow T: A, B\)
-
\(T \rightarrow A: \lbrace B, K_{AB}, t, \lbrace A, K_{AB}, t \rbrace_{K_B} \rbrace_{K_A}\)
-
\(A \rightarrow B: \lbrace A, K_{AB}, t \rbrace_{K_B}\)
Bob checks that \(t\) is recent, and Alice checks the same timestamp in her part of message 2. An adversary without the long-term keys cannot change either timestamp. The ticket now establishes that Trent issued the key recently. It does not, by itself, prove that the party presenting it knows the key. A protected exchange is still needed for that assurance.
Alice, Bob, and Trent need synchronized clocks, and Bob has to accept tickets within a tolerance window. A replay inside that window still succeeds unless Bob remembers the tickets he has recently accepted.
In 1987, Dave Otway and Owen Rees published a protocol that avoids synchronized clocks. Both parties send nonces to Trent, whose replies include the respective nonces. Each party can then check that its key was issued for its current request. The appendix shows the message flow.
Kerberos
Kerberos builds on Needham-Schroeder and the Denning-Sacco fix, applying them to a network of users and services. It was developed at the Massachusetts Institute of Technology (MIT) for Project Athena, a campus computing project, and described in a 1988 paper. Version 5 was standardized in 1993 and revised in 2005. Microsoft adopted it as the default authentication protocol for Active Directory domains with Windows 2000. Linux and macOS also support it. The name comes from the three-headed dog that guards the underworld in Greek mythology (the dog’s name is usually spelled as Cerberus in English and it probably looked like Fluffy in the first Harry Potter movie).
The problem Kerberos solves is familiar from any organization’s network. Thousands of users need access to file servers, printers, mail, and databases. Each user should log in once, and passwords should never cross the network.
The Authentication Server and the Ticket-Granting Server
Kerberos divides Trent into two services, which usually run on the same machine:
-
The authentication server (AS) verifies a user at login.
-
The ticket-granting server (TGS) issues tickets for individual services.
In password-based Kerberos login, the user’s long-term key \(K_A\) is derived from the password by a key derivation function (similar to applying a seed to a pseudorandom number generator). When Alice logs in, her workstation requests credentials from the AS. The reply contains a session key for talking to the TGS, encrypted under \(K_A\), and a ticket-granting ticket (TGT). The TGT contains Alice’s name, the same session key, and a validity period, encrypted under the TGS’s key.
The workstation derives \(K_A\) from the password Alice typed and decrypts its copy of the session key. It can then discard the password and \(K_A\) for the remainder of these exchanges.
When Alice wants to reach a file server, her workstation sends the TGT to the TGS, along with the service’s name and proof that it holds the TGT’s session key. The TGS returns a new session key protected under that existing key. It also returns a service ticket containing the new key and Alice’s identity, encrypted under the file server’s long-term key. Alice presents the service ticket to the file server with another proof of key possession, called an authenticator.
The TGT and its session key let the workstation request service tickets without reusing the password-derived key. They remain usable until the ticket expires, for a lifetime set by the organization’s policy. This supports single sign-on, where one login gives access to participating services without repeated password prompts. Each service still decides what Alice is authorized to do.
Tickets and Authenticators
A ticket alone does not prove anything about the party presenting it. Tickets travel over the network, so an adversary can copy one.
When presenting a ticket to the TGS or a service, the client includes an authenticator. It contains the client’s name and the current time, encrypted under the ticket’s session key. The recipient decrypts the ticket, extracts that key, and verifies the authenticator’s identity and timestamp. Someone holding only a copied ticket cannot create a new authenticator.
For mutual authentication, the service returns the authenticator’s timestamp in a protected reply. Kerberos distinguishes the client’s and server’s message types cryptographically, so reflecting the client’s message back does not work. The application can use the session key to protect later traffic, but authenticating with Kerberos does not automatically encrypt that traffic.
Timestamps come directly from the Denning-Sacco fix. Tickets contain validity periods, and authenticators contain the time they were created. Services reject authenticators outside a tolerance window, five minutes by default, and remember the ones they have recently accepted so that a replay within the window also fails.
The complete exchange takes six messages. The simplified version below omits nonces and ticket lifetimes, and the appendix gives the full version. Here, \(K_{TGS}\) and \(K_S\) are the long-term keys of the TGS and the service, \(K_{A,TGS}\) and \(K_{A,S}\) are session keys that the KDC creates, and \(t\) is a timestamp. The six messages are:
-
\(A \rightarrow AS: A, TGS\)
Alice’s workstation asks the AS for credentials to use the TGS. -
\(AS \rightarrow A: \lbrace K_{A,TGS} \rbrace_{K_A}, \lbrace A, K_{A,TGS} \rbrace_{K_{TGS}}\)
The AS returns a session key encrypted under Alice’s password-derived key, which only her workstation can decrypt. The second part is the TGT, which only the TGS can read. -
\(A \rightarrow TGS: \lbrace A, K_{A,TGS} \rbrace_{K_{TGS}}, \lbrace A, t \rbrace_{K_{A,TGS}}, S\)
Alice sends the TGT, an authenticator proving she holds \(K_{A,TGS}\), and the name of the service she wants. -
\(TGS \rightarrow A: \lbrace K_{A,S} \rbrace_{K_{A,TGS}}, \lbrace A, K_{A,S} \rbrace_{K_S}\)
The TGS returns a new session key for the service, encrypted under the key Alice shares with the TGS. The second part is the service ticket, which only the service can read. -
\(A \rightarrow S: \lbrace A, K_{A,S} \rbrace_{K_S}, \lbrace A, t \rbrace_{K_{A,S}}\)
Alice presents the service ticket and a new authenticator. The service decrypts the ticket with its own key, obtains \(K_{A,S}\), and checks the authenticator’s timestamp. -
\(S \rightarrow A: \lbrace t \rbrace_{K_{A,S}}\)
If Alice asked for mutual authentication, the service returns the timestamp encrypted under the session key, showing that it could decrypt the ticket.
Messages 1 and 2 happen once per login. Messages 3 and 4 repeat for each new service, and messages 5 and 6 repeat for each connection to that service. The tickets play the role of the Needham-Schroeder ticket, and the timestamps in tickets and authenticators follow the Denning-Sacco fix.
The Cost of a Central Key Server
Kerberos has three costs, and each follows from the design rather than from any bug:
-
The KDC must be available to issue new tickets. Clients can continue using cached, unexpired service tickets during an outage. Organizations run replicas to keep ticket issuance available.
-
The KDC holds the long-term keys of every user and service it administers. Compromising it can let an attacker impersonate users and issue fraudulent tickets.
-
Clients, services, and the KDC need clocks that agree within the configured tolerance. Excessive clock drift causes authentication failures.
Guessing Passwords from Kerberos Tickets
A key derived from a password is only as strong as the password. Kerberos protects passwords on the wire, and it cannot make a weak one strong.
Service, rather than user, accounts are the usual target. A service ticket is encrypted under the service’s long-term key. Some services in Windows domains use accounts with human-chosen passwords. An authenticated domain user can normally request a ticket for a registered service without being authorized to use that service. An attacker can then test password guesses against the ticket offline. Ticket requests can be logged, but the later guesses do not generate failed login attempts. This attack is known as Kerberoasting.
Long, randomly generated service-account passwords make this guessing impractical. Automatically managed service accounts also remove the need for people to choose and rotate these passwords.
What Each Protocol Added
The protocols in this family differ mostly in how they establish freshness, and in which party gets the evidence:
| Protocol | What it added | Remaining limitation |
|---|---|---|
| Basic protocol | A ticket that Alice forwards and cannot read | No freshness checks |
| Needham-Schroeder (1978) | Nonces and proof of session-key possession | Bob cannot tell whether the key is recent |
| Denning-Sacco (1981) | A timestamp inside the ticket | Requires clocks, duplicate detection, and a separate proof of key possession |
| Kerberos | Separate AS and TGS roles, single sign-on, and authenticators | Depends on the KDC for new tickets, synchronized clocks, and strong credentials |
Next: Part 3: Public Key Authentication and TLS
Lecture 4: Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Appendix
Lecture 4 Study Guide | List of terms