MS LSA is a protected subsystem that authenticates and logs users onto the local system. The user credential is stored at the native credential cache of LSA on Windows. This kind of credential is often used to authenticate the user to the server, one of the authentication methods is Kerberos. JGSS has provided a native interface which can read the native TGT credential and use it to get the TGS of a service. But how does JGSS read the native TGT credential?
Here is a sample code for reading native credential using JGSS:
import sun.security.krb5.Credentials; import sun.security.krb5.internal.Ticket; public class TestLSACredential { public static void main(String[] args){ Credentials cred = Credentials.acquireDefaultCreds(); System.out.println("==============CREDENTIAL START===================="); System.out.println("Client : " + cred.getClient().getName()); System.out.println("Server : " + cred.getServer().getName()); //Session key type // DES_CBC_MD5 3 // RC4_HMAC 23 System.out.println("Session key type : " + cred.getSessionKey().getEType()); System.out.println("Start time : "+cred.getStartTime().getTime()+ " GMT time : "+cred.getStartTime().toGMTString()+ " Local time : "+cred.getStartTime().toLocaleString()); System.out.println("End time : "+cred.getEndTime().getTime()+ " GMT time : "+cred.getEndTime().toGMTString()+ " Local time : "+cred.getEndTime().toLocaleString()); System.out.println("AUth time : "+cred.getAuthTime().getTime() + " GMT time : "+cred.getAuthTime().toGMTString() + " Local time : " + cred.getAuthTime().toLocaleString()); //Print ticket info Ticket tkt = cred.getTicket(); System.out.println("Ticket realm : "+tkt.realm); System.out.println("Ticket server : "+tkt.sname.getName()); System.out.println("Ticket flags : "+cred.getTicketFlags()); System.out.println("=============CREDENTIAL END========================="); } }
The process of reading the native credential consists of two steps internally:
-
The native credential is read out from MS LSA, then the validity of the credential will be checked. This check includes the session key type check, the end time check and the ticket flag check.
-
If the native TGT credential is valid, then it is returned to the JGSS API to request a TGS; otherwise, a new request will be sent to the KDC to retrieve an usable TGT
When checking the native TGT credential validity, the first thing to check is whether the session key type of the TGT is supported.
The session key type of the native TGT is determined by the KDC when the user logins to the system, the client system may propose an encryption key type to the KDC, if the KDC supports it, it will generate a TGT with the proposed encryption key type, otherwise, the KDC will choose the one it supports and has the highest security level. Starting from Windows 7/Windows Server 2008 R2, the user can update the Group Policy to enable some specified encryption types, the setting can be set by following below steps:
-
Start -> Run -> gpedit.msc
-
Go to Computer Configuration\Windows Settings\Security Settings\Local Policies\Security Options.
-
On right panel, find Network security: Configure encryption types allowed for Kerberos
You can use klist command to list the native TGTs on the MS LSA cache.
Then the session key type of the TGT will be checked against a list of etypes to see whether it's supported. This list is determined by the default_tkt_enctypes option in the krb5.ini/krb5.conf. The user can specify the krb5 config path with the system property -Djava.security.krb5.conf = krb5.conf or by putting it in the C:\Windows or C:\WinNT folder.
Below is table of the available encryption type and the corresponding code:
Encryption Type |
Code (dec, hex) |
des-cbc-crc |
1, 0x1 |
des-cbc-md4 |
2, 0x2 |
des-cbc-md5 |
3, 0x3 |
des3-cbc-sha1 |
5, 0x5 |
des3-cbc-sha1-kd |
16, 0x10 |
aes-128-cts-hmac-sha1-96 |
17, 0x11 |
aes-256-cts-hmac-sha1-96 |
18, 0x12 |
rc4-hmac (arcfour-hmac) |
23, 0x17 |
rc4-hmac-exp |
24, 0x18 |
If the session key type is supported, then the TGT end time will be checked against the current system time to see whether it's expired.
The last thing to check is the ticket flag, if the flag is invalid, the TGT will be ignored as well.
If every check is OK, the native credential will be returned and it is used to request the TGS for a specified service.