In a Kerberos AS-REP, which key seals the ticket-granting ticket and which key seals the enc-part beside it?
answer
- two parts, two different keys
- one part the client cannot open
- opaque blob plus a session key
- krbtgt key seals the ticket itself
- enc-part under the client's long-term key
basics
~20 sThe ticket-granting ticket is sealed under the krbtgt principal's long-term key, so the requesting client cannot open it. The AS-REP's enc-part beside it is sealed under the client's own long-term key and carries the session key, the ticket flags and the expiry times.
solid answer
~40 sAn `AS-REP` is two encrypted blobs under two different keys. The `ticket` field is the ticket-granting ticket, encrypted under the long-term key of the `krbtgt/REALM@REALM` principal; the client holds it as an opaque blob and never decrypts it. The `enc-part` beside it is encrypted under the **client's own long-term key**, and once the client derives that key it recovers the session key the KDC generated, the echoed `nonce`, the granted `TicketFlags`, `authtime`, `endtime` and, if the ticket is renewable, `renew-till`. The same session key sits inside the ticket too, where only a holder of the `krbtgt` key can read it. That asymmetry is the whole design: the client can prove it holds the session key without being able to alter, inspect or forge the statement the KDC sealed about it.
code
asn1 · 23 lines-- AS-REQ ::= [APPLICATION 10] KDC-REQ
KDC-REQ ::= SEQUENCE {
pvno [1] INTEGER (5),
msg-type [2] INTEGER (10), -- AS
padata [3] SEQUENCE OF PA-DATA OPTIONAL,
req-body [4] KDC-REQ-BODY
}
KDC-REQ-BODY ::= SEQUENCE {
kdc-options [0] KDCOptions,
cname [1] PrincipalName, -- the requesting principal
realm [2] Realm,
sname [3] PrincipalName, -- krbtgt/REALM@REALM
till [5] KerberosTime, -- requested expiry
nonce [7] UInt32,
etype [8] SEQUENCE OF Int32
}
-- AS-REP: the two sealed parts
-- ticket : encrypted under the krbtgt principal's long-term key
-- enc-part : encrypted under the client's long-term key, and once
-- opened yields key, nonce, flags, authtime, endtime,
-- renew-till, srealm, snamego deeper
Recall that the reply has two parts and only one of them is meant for you. The ticket is carried, not read; the part you can decrypt tells you the session key and when it expires.
Explain the mechanics: which key seals which half, why the session key appears in both, and what the client checks before accepting the reply. Name the fields rather than gesturing at 'the encrypted bit'.
Show the operational consequence: a relayed ticket must be byte-identical, a cached ticket without its session key is useless, and a client that cannot open enc-part has a key-derivation problem rather than an authorization problem.
The tradeoff to discuss is statelessness. Sealing the statement rather than remembering it lets the KDC scale and survive restarts, at the price of revocation being bounded by endtime rather than immediate.
## What the AS exchange is for A Kerberos client that has just started holds one durable secret: its **long-term key**, derived from a password by `string-to-key` or stored as a key on the host. It holds no tickets. The **AS exchange** is the single round trip that converts that long-term key into a **ticket-granting ticket** plus a freshly generated **session key**, and every later exchange in the protocol spends what this one produced. The request is an `AS-REQ` (`[APPLICATION 10] KDC-REQ`): an optional `padata` list and a `KDC-REQ-BODY` carrying the client name `cname`, the realm, the requested `sname` — for a ticket-granting ticket that is the `krbtgt/REALM@REALM` principal — a `nonce`, a requested expiry `till`, and the encryption types the client can handle. The reply is an `AS-REP`, and its shape is what this question turns on. ## The two halves of the reply | Part of the `AS-REP` | Sealed under | Can the requesting client open it? | What it carries | |---|---|---|---| | `ticket` | the `krbtgt` principal's long-term key | **No** | `EncTicketPart`: `flags`, the session `key`, `crealm`, `cname`, `authtime`, `starttime`, `endtime`, `renew-till`, `caddr`, `authorization-data` | | `enc-part` | the **client's** long-term key | **Yes** | the same session `key`, the echoed `nonce`, the granted `TicketFlags`, `authtime`, `endtime`, `renew-till`, `srealm` and `sname` | The session key therefore exists in two places at once, wrapped for two different readers. The KDC put it inside the ticket for whoever can open the ticket, and beside the ticket for the client. ## Why the client cannot read the ticket The ticket is not addressed to the client at all. It is a statement the KDC makes **to a later reader** — for a ticket-granting ticket, to the ticket-granting service, which holds the `krbtgt` key. Sealing it under a key the client does not hold gives three properties at once: - **Integrity.** The client cannot edit `cname`, stretch `endtime`, or switch on a flag it was not granted, because it cannot produce valid ciphertext under the `krbtgt` key. - **Opacity that does not matter.** The client loses nothing by being unable to read it, because everything it needs is repeated in plaintext to it inside `enc-part`. - **Statelessness at the KDC.** The KDC need not remember what it issued; the sealed ticket carries the whole statement back to it. ## What the client does with each half 1. It derives its long-term key and decrypts `enc-part`. 2. It checks the `nonce` in `enc-part` against the one it generated in the `KDC-REQ-BODY`. A mismatch means the reply does not answer this request, and the client discards it. 3. It stores the session key and the opaque `ticket` together as one credential. 4. Later, it presents the ticket unmodified and demonstrates possession of the session key. Spending the ticket-granting ticket for a service ticket is the ticket-granting service's exchange, not this one. Step 3 is the part candidates most often get wrong: the ticket **alone** is not a usable credential. Without the session key, a holder can replay the bytes but cannot construct anything keyed to them. ## What the split does and does not prove What the structure proves is narrow and worth stating precisely: - It proves the **KDC** issued this ticket, to any later reader holding the sealing key. - It proves, to the client, that the reply was produced by something holding the **client's long-term key** — in practice the KDC, since only the KDC and the client hold it. - It does **not** prove that a person was present. Possession of the long-term key is the whole test the AS exchange applies. - It does **not** hide the client's identity: `cname` and `crealm` travel in the clear in both the request and the reply. ## The usual failure The classic symptom of getting this wrong is a client that decrypts `enc-part` fine and then fails at every later step, because it re-encoded the `ticket` instead of carrying the exact bytes it received. A ticket is not a structure the client owns; it is ciphertext to be relayed byte for byte. The second classic symptom is a client that caches the ticket but discards the session key on restart and cannot understand why a ticket it plainly still holds no longer works.
- What stops a captured AS-REP from an earlier exchange being accepted by the client?The client generates a fresh `nonce` in the `KDC-REQ-BODY` and the KDC echoes it inside `enc-part`. A replayed reply carries the old value, so the check fails and the client discards it. The `endtime` in the same structure bounds how long the credential is usable even when the reply is genuine.
- If the client never decrypts the ticket, how does it know which flags and expiry it was granted?From `enc-part`, not from the ticket. The KDC repeats the granted `TicketFlags`, `authtime`, `endtime` and `renew-till` in the part sealed under the client's long-term key precisely so the client can see what it got. The copies inside the ticket are for the reader who can open it.
- What does the KDC send when it has no record of the requested client principal?A `KRB-ERROR` (`[APPLICATION 30]`) carrying `KDC_ERR_C_PRINCIPAL_UNKNOWN (6)`. There is no ticket and no `enc-part` to open, so the client learns nothing about whether any credential would have worked — the error is about the name, not the key.
Think of a sealed courier pouch addressed to a clearing office: you carry it but hold no key to it. The covering note handed to you in your own cipher tells you the one-time code that is also sealed inside the pouch.
saying these in an interview costs you the question
- Says the client decrypts the ticket-granting ticket to read its flags.
- Claims both halves of the AS-REP are sealed under one key.
- Thinks the password or long-term key travels inside the AS-REP.
- Says the ticket alone is enough to use, without the session key.
- Believes the session key is generated by the client, not the KDC.