问题
We are reconfiguring a SPNEGO / Kerberos SSO application to use AES128 / AES256 instead of the the weak encryption ciphers DES and RC4.
Some days ago I posted a preparatory question: Now we have a concrete error.
The token supplied to the function is invalid.
The components:
The Kerberos “back-end” is Windows Active Directory
The Application Server uses pure Java GSSAPI and runs on Windows Server.
The client runs on Windows 10, and is written in Java. It has 2 SPNEGO / SSO implementations:
- pure Java GSSAPI
- native Windows SSPI via Waffle and JNA.
We can switch the client SSO implementation by configuration. As SSPI and GSSAPI are interoperable, in either case the server remains pure Java GSSAPI.
The client and server use the SPNEGO protocol, but only support Kerberos, not NTLM.
In the “old” setup, using enctype RC4, the client is successfully authenticated, and successfully validates the SPNEGO token in the response from the server using either GSSAPI or SSPI.
The new configuration:
We then made changes to the configuration of the client, server, SPN, etc, removing RC4 / DES and enabling AES128.
After that change:
1) klist shows that the client has an AES128 TGT for the server SPN.
2) Using GSSAPI: the client is successfully authenticated by the server, and successfully validates the SPNEGO token in the response from the server —> OK.
3) Using SSPI: the client is successfully authenticated by the server, but cannot validate the SPNEGO token in the response from the server —> NOT OK.
The problem:
Instead we get the error: ”The token supplied to the function is invalid”.
Reading the Waffle code indicates that this error likely comes from Secure32.dll https://github.com/Waffle/waffle/blob/0c6f832222b59537847281adf7d2959583809dff/Source/WindowsAuthProvider/Secur32.cs
The “invalid” token starts with “oY…” indicating a KRB_AP_REP, and looks very similar to the tokens created using RC4, other than it is slightly longer.
As the token can validated using GSSAPI, I am reasonably sure that it is valid. Instead we suspect that the problem lies with the configuration of Windows 10 Workstation or user.
Googling for the error produces some hits, but none directly related to SSPI / SPNEGO SSO. I am reluctant to hack random registry settings without a clearer understanding of what we are changing. e.g.
TLS 1.2 - The token supplied to the function is invalid
SQL Server error after update: The token supplied to the function is invalid
Any ideas?
Note: While the pure GSSAPI client currently works, this option will die if Windows Credential Guard is activated (thus blocking access to the TGT). Once that happens, SSPI will be the only viable solution.
Update
We have spent a morning using Wireshark to analyse the requests and responses, and have discovered the following:
Request from Client using GSSAPI
- negTokenInit / MechTypes —> contains only 1 mech type: for KRB5
Request from Client using SSPI
- negTokenInit / MechTypes —> contains 4 mech types: for KRB5, MS KRB5, NEGOEX and NTLMSSP
Response from GSSAPI to a GSSAPI request using AES128 (token OK)
- This response token is 32 chars long, and is identical that that produced on my Linux development environment. e.g.
oRQwEqADCgEAoQsGCSgGSIb3EgECAg==
Response from GSSAPI to a SSPI request using RC4 (token OK)
Wireshark —> TODO: Given that the token is much longer than that made to a GSSAPI request. It will be interesting to see what is contains.
This response token is 320 chars long. e.g.
oYHrMIHooA…CZKm8y+Kx8sow==
Response from GSSAPI to a SSPI request using AES128 (token NOT OK)
Wireshark does not show this response using the Http filter - even though the client receives the response, inc. body. Wireshark only shows the response as TCP/IP packets. We suspect that Wireshark has the same problem as SSPI in processing this as an SPNEGO token.
This response token is 328 chars long, i.e. 8 chars longer than the RC4 equivalent above. e.g.
oYHzMIHwoA…4AE6jfTHu+U2qMMestyHKpH
We initially suspected that this token might have been mangled (e.g. cut short) “in-transit”, but could prove that the token was identical in length before being added by the server to the response headers to that received by the client.
The token is taken direct from the GSSAPI, before being base64 encoded and added to the response headers.
byte token[] = gssContext.acceptSecContext(gssapiData, offset, gssapiData.length);
We updated the Application Server from Oracle Java 8u45 to AdoptOpenJDK 11.0.6, but this changed nothing.
来源:https://stackoverflow.com/questions/60422387/the-token-supplied-to-the-function-is-invalid-error-when-validating-spnego-res