What does a KDC's KDC_ERR_PREAUTH_REQUIRED reply to a Kerberos AS-REQ tell the client to do?
answer
- the first request is supposed to fail
- an error that advertises what to send
- e-data lists acceptable pre-authentication types
- encrypted current timestamp as proof
- PA-ENC-TS-ENC under the long-term key
basics
~20 sKDC_ERR_PREAUTH_REQUIRED (25) means the KDC will not issue a ticket until the client proves it holds its long-term key. The error's e-data carries METHOD-DATA listing the pre-authentication types accepted, and the client resends the AS-REQ with PA-ENC-TIMESTAMP.
solid answer
~40 sWhere a principal's policy requires Kerberos pre-authentication, the first `AS-REQ` is expected to fail: the KDC answers with a `KRB-ERROR` carrying `KDC_ERR_PREAUTH_REQUIRED (25)`, and the `e-data` field holds `METHOD-DATA` — a list of `PA-DATA` entries naming which pre-authentication types it will accept and the parameters the client needs, typically `pa-etype-info2 (padata-type 19)`, sometimes `pa-etype-info (padata-type 11)` or `pa-pw-salt (padata-type 3)`. The client derives its long-term key using those parameters and resends the same request with a `padata` entry of type `pa-enc-timestamp (padata-type 2)`, whose value is a `PA-ENC-TS-ENC` structure — `patimestamp` and optional `pausec` — encrypted under that key. A current timestamp the client could only have encrypted with the long-term key is the proof of possession; the KDC decrypts it, checks the time against its own clock, and issues the `AS-REP`.
code
asn1 · 21 lines-- 1. Bare AS-REQ: no padata. KDC answers KRB-ERROR.
KRB-ERROR ::= SEQUENCE {
msg-type [1] INTEGER (30),
error-code [6] Int32, -- 25 = KDC_ERR_PREAUTH_REQUIRED
e-data [12] OCTET STRING -- holds METHOD-DATA
}
-- METHOD-DATA ::= SEQUENCE OF PA-DATA, e.g.
-- padata-type 19 (pa-etype-info2)
-- padata-type 3 (pa-pw-salt)
-- 2. The client retries with the proof attached.
PA-DATA ::= SEQUENCE {
padata-type [1] Int32, -- 2 = pa-enc-timestamp
padata-value [2] OCTET STRING -- encrypted PA-ENC-TS-ENC
}
PA-ENC-TS-ENC ::= SEQUENCE {
patimestamp [0] KerberosTime, -- the client's current time
pausec [1] Microseconds OPTIONAL
}go deeper
Recall the shape: the client asks, the KDC says 'prove you hold the key first', and the client asks again with an encrypted timestamp attached. The first refusal is normal traffic.
Explain the mechanics: error code 25, the METHOD-DATA in e-data that advertises acceptable types, and the PA-ENC-TS-ENC structure encrypted under the long-term key as the proof of possession.
Show the diagnosis. Separate code 25 from a pre-authentication failure and from a clock-skew rejection, and say which of the three a login loop, a wrong salt and a drifting host clock each produce.
The judgment is about policy uniformity: requiring pre-authentication everywhere costs a round trip and a clock dependency, while exempting principals to make an integration work weakens the guarantee the whole realm rests on.
## The first request is meant to fail The surprising thing about Kerberos pre-authentication is that the protocol's normal path includes an error. A client that does not already know the realm's policy sends a bare `AS-REQ` with no `padata`. Where the requested principal's policy requires pre-authentication, the KDC does not issue anything; it replies with a `KRB-ERROR` (`[APPLICATION 30]`) whose error code is `KDC_ERR_PREAUTH_REQUIRED (25)`. That is not a credential failure and it says nothing about whether the client's key is right. It is the KDC telling the client which proof it must attach, and it is the reason a log full of code 25 on first contact is ordinary traffic rather than an incident. ## What the error actually carries The useful content is in the error's `e-data` field, which holds a `METHOD-DATA` sequence — a list of `PA-DATA` entries. Each entry names a pre-authentication type and may carry parameters the client needs to construct its proof. | `padata-type` | Name | Direction | Purpose | |---|---|---|---| | 2 | `pa-enc-timestamp` | client to KDC | the proof itself: an encrypted `PA-ENC-TS-ENC` | | 3 | `pa-pw-salt` | KDC to client | the salt string the client needs to derive its long-term key | | 11 | `pa-etype-info` | KDC to client | acceptable encryption types with their salts | | 19 | `pa-etype-info2` | KDC to client | the current form of that hint, used in preference to type 11 | | 1 | `pa-tgs-req` | client to KDC | belongs to the ticket-granting exchange, never to the AS exchange | So the error is also a **capability advertisement**. Without it, a client would have to guess both which pre-authentication method the realm accepts and which parameters to derive its key with. ## The second request The client resends the `AS-REQ` unchanged except for one added `padata` entry: 1. It derives its long-term key using the parameters the KDC advertised. 2. It reads its own clock and builds `PA-ENC-TS-ENC` with `patimestamp` and, optionally, `pausec` for sub-second precision. 3. It encrypts that structure under the long-term key and puts the ciphertext in a `PA-DATA` of type 2. 4. It sends the request again, with the same `cname`, `sname` and a fresh `nonce`. The KDC decrypts the value with the key it holds for that principal. Success means the requester holds the long-term key. The timestamp then has to be within the realm's allowed clock skew of the KDC's own time; if it is not, the KDC rejects it with `KRB_AP_ERR_SKEW`. ## Why a timestamp, and what it proves An encrypted **current** timestamp is a cheap freshness proof that costs no extra round trip. A plain encrypted constant would be replayable forever; a timestamp is only valid inside a narrow window, and the KDC can refuse anything outside it. What it proves is exactly one thing: **something holding the principal's long-term key produced this request recently.** It does not prove a person was at a keyboard, it does not prove which host the key was used from, and it does not bind the request to any hardware. ## When the KDC does not ask for it Pre-authentication is a per-principal policy, not a property of the protocol's message flow. Where a principal's policy does not require it, the KDC answers the very first `AS-REQ` with an `AS-REP` — a reply whose `enc-part` is sealed under that principal's long-term key. That is the structural reason realms require pre-authentication by default; what an adversary does with such a reply is the business of the attack-focused material, not of this exchange. ## The other errors you will meet here - `KDC_ERR_ETYPE_NOSUPP (14)` — none of the encryption types the client offered in the request body is acceptable to the KDC for this principal. This is decided before any pre-authentication value is evaluated. - `KDC_ERR_PREAUTH_FAILED` — a pre-authentication value was supplied and did not verify: the wrong key, or the right key derived with the wrong parameters. - `KRB_AP_ERR_SKEW` — the value decrypted, but `patimestamp` is too far from the KDC's clock. - `KDC_ERR_MORE_PREAUTH_DATA_REQUIRED` — a multi-step pre-authentication method is in progress and the exchange is not finished. Telling `KDC_ERR_PREAUTH_REQUIRED (25)` apart from `KDC_ERR_PREAUTH_FAILED` is the single most useful diagnostic distinction in this exchange: the first is the protocol working, the second is a key problem.
- A KDC returns KDC_ERR_ETYPE_NOSUPP (14) instead. What went wrong?None of the encryption types the client listed in the `KDC-REQ-BODY` is one the KDC will use for that principal, so there is nothing to seal a reply with. It is decided from the request body before any pre-authentication value is looked at, which is why a correct key still produces this error.
- How do you tell KDC_ERR_PREAUTH_REQUIRED apart from KDC_ERR_PREAUTH_FAILED when diagnosing a login loop?Code 25 means no pre-authentication value was supplied yet and the KDC is asking for one — the expected first step. `KDC_ERR_PREAUTH_FAILED` means a value was supplied and did not verify, so the client derived the wrong long-term key. A client stuck alternating between the two is deriving its key with parameters the KDC did not advertise.
- Why does the KDC advertise the pre-authentication types rather than the client simply trying one?Because the client must derive its long-term key before it can encrypt anything, and derivation needs parameters the KDC holds — which is what `pa-etype-info2` and `pa-pw-salt` carry. Advertising also lets a realm change accepted methods without every client being reconfigured first.
saying these in an interview costs you the question
- Says the first AS-REQ failing means the credential was wrong.
- Claims the client sends its long-term key inside the padata.
- Thinks the timestamp travels in the clear and is merely compared.
- Believes pre-authentication is negotiated before any AS-REQ is sent.
- Says every principal in a realm must use pre-authentication.