What is a keytab
We can commonly use SSO for Microsoft services running on a computer joined to a domain. In this case, the computer and AD share a password, from which they create a Secret Key. This key is then used to encrypt mutual communication. If we want to use SSO on a service that cannot communicate with the DC, for example, running on Linux, not in a domain, etc., it is sufficient if it knows the Secret Key for decrypting communication (it must share it with the DC).
Keytab (key table) is a file that contains SPNs and their corresponding encryption keys (Secret Key). It can be used for decrypting communication in SSO and thus authenticating a client accessing the service. It can also be used for domain authentication (without needing to enter a username and password). A keytab file can contain one or more SPNs/keys.
Using a keytab file replaces the need for a computer to be joined to a domain (and thus have encrypted communication with the DC). The file contains the encryption key. Of course, we also need the corresponding entry in the domain. This is done by creating a service user account (theoretically, a computer account can be used, but there can be various issues, so it is better to stick with a user account) and registering the SPN for the service on this account. The account must use the same password as the keytab file.
Note: From what we have discussed, it is clear that security must be considered. The keytab file represents user credentials, and it can be used to log into the domain. Therefore, the service account should not have any special privileges (it does not need any for our purposes), and access to the keytab file should be as secure as possible.
Creating a Keytab file
As part of Windows Server 2008 and newer (or in Support Tools for older versions), we find the command-line tool ktpass. This command performs several operations. First, it registers the SPN (Service Principal Name) according to the specified Principal Name and account. By default, it also sets the UPN (User Principal Name) on the account to the value of the Principal Name. It changes the password on the account and uses this for the keytab file. Finally, it creates the output keytab file.
Note: Some versions of ktpass on Windows Server 2003 had a bug, version 5.2.3790.1830 is affected, so a newer version is needed.
Below is an example of creating a keytab file for a web server, first in general form and then with sample values.
Note: Like most other commands, we must run ktpass with sufficient privileges and as an administrator (cmd Run as administrator).
ktpass -out filename -princ HTTP/hostname@AD-DOMAIN -mapUser AD-account -mapOp set -pass * -ptype KRB5_NT_PRINCIPAL -kvno 0 ktpass -out myweb.keytab -princ HTTP/myweb.company.local@COMPANY.LOCAL -mapUser company\myweb-sso -mapOp set -pass * -ptype KRB5_NT_PRINCIPAL -kvno 0
In the above example, we use the following parameters:
out
- output, i.e., the output fileprinc
- Principal Name is case-sensitive, contains the SPN (service/address) and Kerberos Realm, i.e., the domain in which the account is located (written in uppercase)mapUser
- Mapping User - the domain account to which the SPN is registered, generally should be a user account, but in some cases, a computer account can be used, UPN can be specified, but it is safer to use the form domain\sAMAccountNamemapOp
- Mapping Operation specifies whether the SPN is added (add
) or set (set
), which removes all previous SPN entriespass
- Password - to create the keytab file, we must enter the password used to generate the key and set it on the account. An asterisk means it will prompt for the password during creation. Interestingly, if we use an asterisk, we cannot log into the account with the subsequent password, but if we enter the password directly after the parameter, we can log into the account with it. We must consider our password policy; if the entered password does not meet it, an error will be returned (Password set failed).ptype
- Principal Type set to the general typeKRB5_NT_PRINCIPAL
kvno
- Key Version Number represents the key version, which increments with each password change and is stored on the account. The parameter can set a specific value. The version is also stored in the keytab (if not specified by the parameter, the current value from AD is used) and is compared with the value on the account during use. In the keytab, it can be set to 0, and then it is not checked.
We can use several other parameters, some of which are interesting:
target
- specifies which domain controller to use, if not specified, it is automatically detected based on the realm in the Principal Namecrypto
- specifies the encryption method, today the default is RC4-HMAC-NT, for backward compatibility DES-CBC-CRC, DES-CBC-MD5, and others like AES256-SHA1, for the broadest options, we can use the valueAll
, which ensures a ticket is generated for each cipher (into one keytab). If we have an old version of ktpass, it may not support RC4-HMAC-NT and the keytab will not work.setUpn
- if we add the parameter-setUpn
, the UPN on the account will not be set
The example of creating a keytab above corresponds to the method described in many articles on the internet. It involves changing the UPN on the user account. I don't think this is necessary (Kerberos authentication looks for the SPN, not the UPN), so you can use the -setUpn
parameter. I have conducted several tests, and everything works. So below is an example of using ktpass that I find optimal.
ktpass -out myweb.keytab -princ HTTP/myweb.company.local@COMPANY.LOCAL -mapUser company\myweb-sso -mapOp set -pass password -ptype KRB5_NT_PRINCIPAL -kvno 0 -setupn -crypto All
Updated February 8, 2024
UPN is important when using AES encryption. For the RC4-HMAC encryption type, encryption keys are created based solely on the password. But for AES128-CTS-HMAC-SHA1-96 or AES256-CTS-HMAC-SHA1-96, a salt is added. This is formed from the Kerberos Realm (domain name in uppercase) and the user's name (part of the UPN before the @). Keys are created when the password is set for all supported encryption types and stored with the account in AD.
When creating a Keytab file, encryption keys are created in it, and they must match the keys on the account. The ktpass
command takes the specified parameters and creates keys in the file from them (nothing is read from the account in AD). It uses the Principal Name (princ
), from which the user's name and domain are taken, and the password. The problem is that princ
also represents the Service Principal Name (SPN), which is used to find the service. To ensure the keys in the Keytab and AD are the same, we must change the account's UPN (which is the default behavior without the setupn
parameter).
There is another option to preserve the UPN. When creating the Keytab file, we can use the -rawsalt COMPANY.LOCALusername
parameter. Here we specify the salt used when creating the keys in the Keytab.
ktpass -out myweb.keytab -princ HTTP/myweb.company.local@COMPANY.LOCAL -mapUser company\myweb-sso -mapOp set -pass password -ptype KRB5_NT_PRINCIPAL -kvno 0 -crypto AES256-SHA1 -rawsalt COMPANY.LOCALmyweb-sso -setupn
Creating a Keytab file with multiple SPNs
On an application server, we can usually use only one keytab file. However, there may be situations where we need to use multiple SPNs. For example, if we want SSO to work on a web server for both the standard address (FQDN - myweb.company.local) and an alias (www.company.local).
We can do this by first creating a keytab for the first SPN, which we set (set
) on the user account.
C:\>ktpass -out myweb.keytab -princ HTTP/myweb.company.local@COMPANY.LOCAL -mapUser company\myweb -mapOp set -pass * -ptype KRB5_NT_PRINCIPAL -kvno 0 -setupn Targeting domain controller: dc.company.local Using legacy password setting method Successfully mapped HTTP/myweb.company.local to myweb. Type the password for HTTP/myweb.company.local: Type the password again to confirm: Key created. Output keytab to myweb.keytab: Keytab version: 0x502 keysize 72 HTTP/myweb.company.local@COMPANY.LOCAL ptype 1 (KRB5_NT_PRINCIPAL) vno 0 etype 0x17 (RC4-HMAC) keylength 16 (0xad04eaf7d0d0a63adf0596c0788e910c)
Then we call the command again, giving it the first keytab file as input, add the second SPN, and change the Mapping Operation to add
. This creates a keytab that contains two SPNs. When using the same user account, we should enter the same password in both cases.
C:\>ktpass -in myweb.keytab -out myweb.keytab -princ HTTP/www.company.local@COMPANY.LOCAL -mapUser company\myweb -mapOp add -pass * -ptype KRB5_NT_PRINCIPAL -kvno 0 -setupn Existing keytab: Keytab version: 0x502 keysize 72 HTTP/myweb.company.local@COMPANY.LOCAL ptype 1 (KRB5_NT_PRINCIPAL) vno 0 etype 0x17 (RC4-HMAC) keylength 16 (0xad04eaf7d0d0a63adf0596c0788e910c) Targeting domain controller: dc.company.local Using legacy password setting method Successfully mapped HTTP/www.company.local to myweb. Type the password for HTTP/www.company.local: Type the password again to confirm: Key created. Output keytab to myweb.keytab: Keytab version: 0x502 keysize 72 HTTP/myweb.company.local@COMPANY.LOCAL ptype 1 (KRB5_NT_PRINCIPAL) vno 0 etype 0x17 (RC4-HMAC) keylength 16 (0xad04eaf7d0d0a63adf0596c0788e910c) keysize 59 HTTP/www.company.local@COMPANY.LOCAL ptype 1 (KRB5_NT_PRINCIPAL) vno 0 etype 0x17 (RC4-HMAC) keylength 16 (0xad04eaf7d0d0a63adf0596c0788e910c)
We can similarly use two different accounts, each with its own SPN, and create a combined keytab file.
There are no comments yet.