How Kerberos Works, Message by Message
A Kerberos login is three request and reply pairs between a client, the Key Distribution Center (KDC) and a service: the AS exchange gets a ticket-granting ticket (TGT), the TGS exchange turns it into a service ticket, and the AP exchange presents that ticket to the service. Every message is ASN.1 defined in RFC 4120 §5. This page decodes each one with fake values, ties the fields to their sections, and lists what each party must check. For what Kerberos is and where it fits, see the Kerberos standard page.
All examples use the realm EXAMPLE.COM, user ada@EXAMPLE.COM and service HTTP/app.example.com@EXAMPLE.COM. Encrypted parts are shown as their decrypted structure, which only the party holding the key can see.
The sequence at a glance
| # | From → to | Message (msg-type) |
Spec |
|---|---|---|---|
| 1 | Client → KDC (88) | AS-REQ (10) without pre-authentication |
§3.1.1, §5.4.1 |
| 2 | KDC → client | KRB-ERROR (30), code 25 KDC_ERR_PREAUTH_REQUIRED, with PA-ETYPE-INFO2 |
§5.9.1, §5.2.7.5 |
| 3 | Client → KDC | AS-REQ (10) with PA-ENC-TIMESTAMP |
§5.2.7.2 |
| 4 | KDC → client | AS-REP (11): TGT plus encrypted session key |
§3.1.3, §5.4.2 |
| 5 | Client → KDC | TGS-REQ (12) with PA-TGS-REQ carrying an AP-REQ |
§3.3.1, §5.2.7.1 |
| 6 | KDC → client | TGS-REP (13): service ticket |
§3.3.3 |
| 7 | Client → service | AP-REQ (14), inside SMB, LDAP SASL or HTTP Negotiate |
§3.2.2, §5.5.1 |
| 8 | Service → client | AP-REP (15), if mutual authentication was requested |
§3.2.4, §5.5.2 |
Messages 1 to 3: AS-REQ and pre-authentication
AS-REQ ::= [APPLICATION 10] {
pvno 5,
msg-type 10,
padata [ PA-ENC-TIMESTAMP (2): EncryptedData {
etype 18, cipher <PA-ENC-TS-ENC { patimestamp 20261105140211Z,
pausec 412 } encrypted with ada's key> },
PA-PAC-REQUEST (128): include-pac TRUE ],
req-body {
kdc-options forwardable, renewable, canonicalize,
cname { name-type NT-PRINCIPAL (1), name-string ["ada"] },
realm "EXAMPLE.COM",
sname { name-type NT-SRV-INST (2), name-string ["krbtgt", "EXAMPLE.COM"] },
till 20261106000211Z,
rtime 20261112140211Z,
nonce 1953746982,
etype [ 18, 17, 20, 19 ] } }
The first attempt (message 1) is the same without padata. A KDC that requires pre-authentication answers with KRB-ERROR code 25 and a PA-ETYPE-INFO2 hint listing the encryption type and salt to use, and the client retries. The default salt is the realm followed by the name components with no separator, here EXAMPLE.COMada (RFC 4120 §4).
| Field | Meaning | Spec |
|---|---|---|
pvno, msg-type |
Always 5; 10 for AS-REQ, 12 for TGS-REQ. | §5.4.1 |
padata PA-ENC-TIMESTAMP (type 2) |
Current time encrypted in the client's long-term key: proof the client knows the password before the KDC returns anything crackable. | §5.2.7.2 |
PA-PAC-REQUEST (type 128) |
Microsoft extension asking for a PAC in the ticket. | MS-KILE, registered in RFC 4120 §7.5.2 |
kdc-options |
Flags requested for the ticket: forwardable (1), renewable (8), and canonicalize (15, reserved in RFC 4120 and defined in RFC 6806). |
§5.4.1, §2 |
cname, realm |
Client principal and realm. cname appears only in AS-REQ. |
§5.4.1, §5.2.2 |
sname |
krbtgt/EXAMPLE.COM, the ticket-granting service. |
§7.3 |
till, rtime |
Requested end time and renewable-until time; the KDC may shorten them. | §5.4.1 |
nonce |
Random number the KDC must echo inside the encrypted reply. | §5.4.1, §3.1.5 |
etype |
Encryption types in preference order: 18 aes256-cts-hmac-sha1-96, 17 aes128 (RFC 3962), 20 and 19 the SHA-2 variants (RFC 8009). Seeing 23 (RC4-HMAC) here is a finding. | §5.4.1, RFC 8429 §7 |
Message 4: AS-REP
AS-REP ::= [APPLICATION 11] {
pvno 5, msg-type 11,
crealm "EXAMPLE.COM",
cname { NT-PRINCIPAL, ["ada"] },
ticket { -- the TGT, opaque to the client
tkt-vno 5, realm "EXAMPLE.COM", sname krbtgt/EXAMPLE.COM,
enc-part { etype 18, kvno 2, cipher <EncTicketPart encrypted with the krbtgt key> } },
enc-part { etype 18, kvno 7, cipher <EncASRepPart encrypted with ada's key> } }
EncASRepPart (decrypted by the client) {
key { keytype 18, keyvalue <TGT session key> },
last-req [...],
nonce 1953746982,
flags forwardable, renewable, initial, pre-authent,
authtime 20261105140211Z,
endtime 20261106000211Z,
renew-till 20261112140211Z,
srealm "EXAMPLE.COM",
sname krbtgt/EXAMPLE.COM }
| Field | Meaning | Spec |
|---|---|---|
ticket |
The TGT. Its enc-part is encrypted with the krbtgt key, so the client cannot read or alter it. |
§5.3 |
enc-part |
Encrypted with the client's key; contains the session key the client will use with the TGS. | §5.4.2 |
nonce |
Must equal the request nonce, proving the reply is fresh. | §3.1.5 |
flags |
initial (from the AS exchange) and pre-authent (the client was pre-authenticated). |
§5.3, §2 |
kvno |
Key version number, so a service can pick the right key after a password change. | §5.2.9 |
Messages 5 and 6: TGS-REQ and TGS-REP
TGS-REQ ::= [APPLICATION 12] {
pvno 5, msg-type 12,
padata [ PA-TGS-REQ (1): AP-REQ { ticket <the TGT>,
authenticator <Authenticator encrypted with the TGT session key> } ],
req-body {
kdc-options forwardable, canonicalize,
realm "EXAMPLE.COM",
sname { NT-SRV-INST, ["HTTP", "app.example.com"] },
till 20261106000211Z,
nonce 287364510,
etype [ 18, 17 ] } }
The TGS-REP has the same shape as the AS-REP, but its ticket is the service ticket, encrypted with the key of HTTP/app.example.com, and its enc-part is encrypted with the TGT session key rather than the user's password key (§3.3.3). In Active Directory the service key is derived from the password of whichever account holds that SPN. That single fact is Kerberoasting: any authenticated user can request this ticket and attack the service account's password offline.
Messages 7 and 8: AP-REQ and AP-REP
AP-REQ ::= [APPLICATION 14] {
pvno 5, msg-type 14,
ap-options mutual-required,
ticket { tkt-vno 5, realm "EXAMPLE.COM", sname HTTP/app.example.com,
enc-part { etype 18, kvno 4, cipher <EncTicketPart> } },
authenticator { etype 18, cipher <Authenticator encrypted with the service session key> } }
EncTicketPart (decrypted by the service with its own key) {
flags forwardable, pre-authent,
key { keytype 18, keyvalue <service session key> },
crealm "EXAMPLE.COM", cname { NT-PRINCIPAL, ["ada"] },
transited { tr-type 1, contents "" },
authtime 20261105140211Z, starttime 20261105140230Z, endtime 20261106000211Z,
authorization-data [ AD-IF-RELEVANT [ AD-WIN2K-PAC (128): <PAC> ] ] }
Authenticator (decrypted with the session key) {
authenticator-vno 5,
crealm "EXAMPLE.COM", cname { NT-PRINCIPAL, ["ada"] },
cksum <checksum binding the application request, if any>,
cusec 418211, ctime 20261105140230Z,
subkey { keytype 18, keyvalue <optional subkey> },
seq-number 1093845021 }
Over HTTP this AP-REQ travels inside a SPNEGO token: Authorization: Negotiate YIIH... (RFC 4559 §4). With mutual-required, the service replies with an AP-REP whose encrypted part repeats ctime and cusec, proving it could decrypt the ticket (§5.5.2).
| Field | Meaning | Spec |
|---|---|---|
ap-options |
use-session-key (1) for user-to-user, mutual-required (2). |
§5.5.1 |
EncTicketPart.key |
The session key the KDC generated for this client and service. | §5.3 |
authtime, starttime, endtime |
When the user authenticated and the ticket's validity window. | §5.3 |
authorization-data |
Wrapped in AD-IF-RELEVANT; in AD carries the PAC (type 128). |
§5.2.6, MS-PAC |
Authenticator.ctime, cusec |
Client time, the basis of replay protection. | §5.5.1 |
Authenticator.cksum |
Binds the authenticator to application data, for example GSS-API channel bindings. | §5.5.1, RFC 4121 §4.1.1 |
The checks each party must run
Client, on AS-REP (§3.1.5)
cnameandcrealmin the reply match the request; the decryptednonceequals the one sent;snameandsrealmare the expected TGS.- A host that uses a password login to grant local access must not trust the AS-REP alone. RFC 4120 §3.1.5 says decrypting it "is not sufficient for the host to verify the identity of the user"; the host must also get and verify a ticket for its own service key, or a spoofed KDC can log anyone in.
KDC
- Require pre-authentication for every account (§5.2.7.2). Without it, anyone can request an AS-REP for that user and crack the encrypted part offline.
- Issue only strong encryption types and never RC4 or DES for new keys (RFC 8429 §7, RFC 6649).
Service, on AP-REQ (§3.2.3)
- Decrypt the ticket with its own key at the
kvnoindicated (KRB_AP_ERR_BADKEYVER,KRB_AP_ERR_BAD_INTEGRITYon failure), then decrypt the authenticator with the ticket's session key. cnameandcrealmin the authenticator match the ticket (KRB_AP_ERR_BADMATCH), and client addresses match if present.- Client time within the allowable clock skew (
KRB_AP_ERR_SKEW, RFC 4120 uses 5 minutes as its example), and the authenticator is not in the replay cache (KRB_AP_ERR_REPEAT); ticket not yet valid or expired givesKRB_AP_ERR_TKT_NYVorKRB_AP_ERR_TKT_EXPIRED. - Authorize separately. Passing these checks "provides only authentication of the named principal" (§3.2.3). In Active Directory, validate the PAC signatures as MS-PAC describes before trusting group SIDs.
Common implementation mistakes, with the CVEs and techniques behind them
| Mistake | What goes wrong | Real examples |
|---|---|---|
| PAC signatures or requester SID not validated | A forged or borrowed PAC grants privileges | CVE-2024-26248, CVE-2024-29056, CVE-2026-27912 |
| A step skipped in a protocol extension | Identity forged through S4U or certificate logon | CVE-2025-60704 (S4U), CVE-2025-26647 (PKINIT), CVE-2022-26923 |
| Client trusts a KDC reply it cannot authenticate | KDC impersonation by a machine in the middle | CVE-2024-20674 |
| Tickets reflected back to the issuing host | Elevation of privilege over SMB | CVE-2025-33073, CVE-2025-58726 |
| RC4 still issued for service tickets | Service account passwords cracked offline | CVE-2026-20833, Kerberoasting |
| SPN uniqueness checked on look-alike strings | Service name hijack and NTLM downgrade | CVE-2026-25177 |
| Over-broad delegation | A service impersonates any user to any service | Kerberos delegation abuse |
| Certificate templates trusted for logon | PKINIT logons as other users | AD CS certificate template abuse, CVE-2024-49019 |
Try it locally
There is no browser tool for Kerberos, which runs over raw TCP and UDP to the KDC. On a test realm, MIT Kerberos's kinit runs the AS exchange and klist shows the result: klist -e -f prints each ticket's encryption type and flags, so you can confirm no ticket uses etype 23 and that the pre-authent flag is set. A packet capture on port 88 shows messages 1 to 6 in clear structure, with the encrypted parts opaque.
Related
Kerberos standard page, how LDAP works, message by message, how RADIUS works, message by message. Glossary: Kerberos, NTLM, Active Directory.
Frequently asked questions
- What messages are in a Kerberos login?
- Typically six. The client sends AS-REQ, the KDC answers KRB-ERROR with KDC_ERR_PREAUTH_REQUIRED (25), the client resends AS-REQ with an encrypted timestamp, and the KDC returns AS-REP with a ticket-granting ticket. Then TGS-REQ and TGS-REP obtain a service ticket, and AP-REQ (optionally answered by AP-REP) presents it to the service. The message formats are in RFC 4120 section 5.
- What is inside a Kerberos ticket?
- A ticket (RFC 4120 section 5.3) has a cleartext realm and service name and an encrypted part, readable only by the service, containing ticket flags, a session key, the client's realm and name, authtime, starttime, endtime, renew-till, optional client addresses and authorization data. In Active Directory the authorization data carries the PAC with the user's SIDs and groups.
- What must a service check when it receives a Kerberos AP-REQ?
- RFC 4120 section 3.2.3 requires it to decrypt the ticket with its own key of the right version, decrypt the authenticator with the ticket's session key, confirm the client name and realm in both match, check the client time is within the allowable clock skew, reject replays using a replay cache, and reject tickets that are not yet valid or expired. Authorization is a separate decision, and in Active Directory includes PAC validation.
Related on Start with Identity
- GuideHow OpenID Connect Works, Message by Message
OpenID Connect on the wire: discovery, the authentication request, the callback, the token request with PKCE, the token response and a decoded ID token, with ev
- GuideHow SAML 2.0 Works, Message by Message
A field-by-field walkthrough of the SAML 2.0 Web Browser SSO profile: the AuthnRequest, the Response and Assertion, the bindings that carry them, the eight chec
- GuideHow SCIM 2.0 Works, Message by Message
SCIM 2.0 on the wire: discovery, filtered lookup, user creation, PATCH for attribute changes and deactivation, group membership changes and DELETE, with annotat
- CVEFreeIPA anonymous LDAP write plants a Kerberos principal in the admins group
FreeIPA's self-managed OTP token ACI let an anonymous LDAP client create a token entry with extra attributes, which combined with a 389 Directory Server ACI fla
- BlogKerberLoss: invisible Unicode lets an attacker twin a Kerberos SPN
CVE-2026-25177, CVSS 8.8. Active Directory treated look-alike SPNs as unique. Semperis and Shai Laron showed how that becomes service hijack and NTLM downgrade.
- ExpertPrincipal designer of Kerberos
Clifford Neuman was one of the principal designers of Kerberos versions 1 through 4 at MIT's Project Athena, led the version 5 design with John Kohl, and is lea