Kerberos Deep Dive
We will take an in-depth look at the Kerberos authentication protocol.
The name Kerberos came from the three headed dogs that guard the underworld, called Cerberus in the Greek mythology.
Kerberos is used to authenticate users to services. Imagine a big network of lots of users and lots of services. The problem we have here is that the network is untrusted. How do we authenticate all the users to all the services and vice versa? We have to faciliate multiple trusts between the services and the users which can be cumbersome. So instead, we create an authentication server (AS) and all the users and services just have to create trust with the AS.
Realm in Kerberos is the group of systems over which Kerberos has the authority to do authentication. Its basically a domain of an organization. And Kerberos is designed to faciliate authentication between Realms or Domains as well. And the unique identities which are the users and services are called Principals. Kerberos provides means to verify the identities of Principals.
If a client wants to use a service, it first asks an Authentication Server (AS) for credentials for that service/server that it wants access to. There are two methods by which a client can ask Kerberos server for credentials. In the first method, the client asks the AS for the credentials called Ticket Granting Ticket (TGT) which is usually then used with Ticket Granting Server (TGS). In the second method, the client sends a request to the TGS by authenticating itself using the TGT.
At the heart of Kerberos is the Key Distribution Center (KDC) which has both the AS and TGS. When a user first logs in and doesn't have any credentials it sends a request KRB_AS_REQ to the AS to authenticate with the TGS. Which will subsequently be used to get tickets/creds for other local-servers. The AS will reply with either KRB_AS_REP or KRB_ERROR.
KRB_AS_REQ
In the KRB_AS_REQ, the client sends (in cleartext) its own identity and the identity of the server for which it is requesting credentials, other information about the credentials it is requesting, and a randomly generated nonce, which can be used to detect replays and to associate replies with the matching requests. This nonce MUST be generated randomly by the client and remembered for checking against the nonce in the expected reply and it must match between REQ and RES.
KRB_AS_REQ reciept
After the AS receives the KRB_AS_REQ it checks its database of users and their secret keys to see if this user exists, if not then it sends KDC_ERR_C_PRINCIPAL_UNKNOWN. If the server cannot accommodate any encryption type requested by the client, an error message with code KDC_ERR_ETYPE_NOSUPP is returned. If pre-authentication is enabled the client will also send a pre-auth token with the request. If it fails, the AS will send KDC_ERR_PREAUTH_FAILED. If pre-auth is not provided then the AS will return KDC_ERR_PREAUTH_REQUIRED. If there are multiple encryption keys registered for a client in the Kerberos database, then the etype field from the AS request is used by the KDC to select the encryption method to be used to protect the encrypted part of the KRB_AS_REP message that is sent to the client.
KRB_AS_REP
Without pre-authentication the server doesn't know if this user is actually the principal named in the request. So it just sends back KRB_AS_REP which has two parts:
EncASRepPart: encrypted with the clients secret key and it has: TGS name/ID, TImestamp, Lifetime, TGS Session Key.
Ticket (TGT): Second message is encrypted with TGS secret key and it has: users name, TGS name/ID, Timestamp, User IP, mostly importantly TGS session key.
More about clients secret key: it is created using string2key hashing function by taking users password, random salt, kvno (The key version number , commonly abbreviated as kvno, distinguishes between different encryption keys that are stored for a given principal).
KRB_AS_REP reciept
When the client receives the messages it can decrypt the first one with its secret key and retrieve the TGS Session Key. Now first part of authenticating the client is done because the client couldn't have decrypted the first part without having a valid credential!
KRB_TGS_REQ
Next, the client will send KRB_TGS_REQ this time to the TGS . Before it can send, the client has to verify that the service its trying to access is within the realm. It can be pre-configured or found through a nameserver which creates additional security issues as the client now has to authenticate the nameserver. But if the client already knows that realm and SPN for the service but doesn't have TGT for that realm then first it needs to get that. Once the client obtains a TGT for the appropriate realm, it determines which Kerberos servers serve that realm and contacts one of them.
KRB_TGS_REQ actually has three parts:
KRB_TGS_REQ body: in cleartext provides the service’s name, the realm, and flags indicating options (like renewable or forwardable tickets). This part essentially tells the TGS which service the client wants a ticket for.
Ticket (TGT): encrypted with TGS’s secret key (the ticket the client received earlier in the
KRB_AS_REP).Authenticator: This part is encrypted with TGS session key retrieved from the
KRB_AS_REP. This is a fresh proof of the client’s identity, including a timestamp, to prevent replay attacks. The TGS uses the session key to decrypt it and verify the client.
KRB_TGS_REQ reciept
The TGS receives it and the first thing it does is checks to see if the service exists in its database of service name/ID and secret keys. Then the TGS will decrypt the TGT using its secret key and retrieve the TGS session key. This key is then used to decrypt the Authenticator part of the message. It checks if the user name/ID in the authenticator and TGT match. It checks many other fields such as expiry time etc. One important check that the TGS does it verifying the TGS Cache to see if the authenticator it just received is not already in the cache to prevent replay attacks. Also whenever a request is made to the ticket-granting server, the presented ticket(s) is (are) checked against a hot-list of tickets that have been canceled.
KRB_TGS_REP
Now, the TGS will create another message KRB_TGS_REP. The response will include a ticket for the requested server or for a ticket granting server of an intermediate KDC to be contacted to obtain the requested ticket. This message has two parts:
EncTGSRepPart: encrypted with TGS session key (the same session key that was established in the KRB_AS_REP and used by the client to encrypt the authenticator in the KRB_TGS_REQ), This part contains a new session key called Service Session Key to be used by the client and the service server.
Ticket (Service Ticket): encrypted by the Service Secret Key, contains client’s identity, the new session key (for communication with the service), and validity information.
KRB_AP_REQ
Next, the client receives this message and decrypts the first part using session key and takes the Service Session Key. Now it will try to authenticate to the Application Server (AP). The KRB_AP_REQ contains two main parts:
Ticket (Service Ticket): encrypted by the Service Secret Key, contains client’s identity, the new Service Session Key (for communication with the service), and validity information.
Authenticator: encrypted by service session key. A fresh proof of the client’s identity, including a timestamp, encrypted with the session key. Has user name/ID, timestamp etc. The authenticator is used to prevent invalid replay of tickets by proving to the server that the client knows the session key of the ticket and thus is entitled to use the ticket. The KRB_AP_REQ message is referred to elsewhere as the 'authentication header'. Authenticators MUST NOT be re-used and SHOULD be rejected if replayed to a server.
KRP_AP_REQ reciept
When the server receives the KRB_AP_REQ, there can be a lot of room for error.
If the message type is anything other than KRB_AP_REQ the server will send KRB_AP_ERR_MSG_TYPE.
If the key version indicated by the Ticket in the KRB_AP_REQ is not one the server can use (e.g., it indicates an old key, and the server no longer possesses a copy of the old key), the KRB_AP_ERR_BADKEYVER error is returned.
If the USE-SESSION-KEY flag is set in the ap-options field, it indicates to the server that user-to-user authentication is in use, and that the ticket is encrypted in the session key from the server's TGT rather than in the server's secret key.
Because it is possible for the server to be registered in multiple realms, with different keys in each, the srealm field in the unencrypted portion of the ticket in the KRB_AP_REQ is used to specify which secret key the server should use to decrypt that ticket. The KRB_AP_ERR_NOKEY error code is returned if the server doesn't have the proper key to decipher the ticket.
If the decryption routines detect a modification of the ticket (each encryption system MUST provide safeguards to detect modified ciphertext), the KRB_AP_ERR_BAD_INTEGRITY error is returned.
The server decrypts the ticket using its secret key. Now, the Authenticator is decrypted using the service session key. And it validates the information in the Authenticator. If everything looks good, the service will check its cache to provide replay protection.
KRB_AP_REP
Typically the server doesn't need to reply to the client. However, if mutual authentication (authenticating not only the client to the server, but also the server to the client) is being performed, the KRB_AP_REQ message will have MUTUAL-REQUIRED set in its ap-options field, and a KRB_AP_REP message is required in response.
The service will now create the KRB_AP_REP which contains the Service Authenticator. This is encrypted by the symmetric session key and once the client decrypts it, it will verify the service name/ID. Thus the mutual authentication is complete.
The user will cache the encrypted Service Ticket for future use.
Last updated
Was this helpful?
