Hey :) I’m learning about Kerberos. I first read about the MIT Kerberos and then about the uses in Microsoft. I found some difference. I just want to be sure. Is it right that in the original MIT Kerberos a hash of the password never send from the client to the server, but in Microsoft Kerberos it happened?
Huh?
Kerberos is Kerberos. It's a well defined specification and all the different implementations are more or less implemented the same. The Windows implementation certainly has it's share of quirks, but it doesn't in any way send the password hash to the server.
Kerberos uses a key agreement process to exchange messages. Both the client and KDC know the users "long term credential" which is their password hashed using a specific key derivation function. When the client wants to send a message to the KDC, it encrypts it using the long term credential. The KDC knows that credential so it can decrypt it. The response is encrypted in the same way.
Neither party sends the password or its hash to the other in general use.
There are two separate but specific scenarios where this doesn't apply however.
When using a certificate to logon via PKINIT, Windows will include the long term credential in the user PAC of the ticket (so the workstation can decrypt it), encrypted to the Diffie-Hellman derived secret.
The other scenario is when doing FIDO logon, the long term credential is included in an authorization data element.
Both of these scenarios exist to allow clients to support legacy protocols that only understand password authentication.
Related
I'm using SPNEGO in order to implement SSO solution. During the configuration, I was required to use domain user credentials in 2 steps:
In the web.xml of my application:
<init-param>
<param-name>spnego.preauth.username</param-name>
<param-value>myuser</param-value>
</init-param>
<init-param>
<param-name>spnego.preauth.password</param-name>
<param-value>mypassword</param-value>
</init-param>
In the setspn command: setspn -A <mySPN> myuser
When I used this configuration, the username of the user "myuser" was retrieved by the Java application using getRemoteUser(). So the SSO worked fine. But when I tried to open a session as other users (on the same windows server) it worked also, so I am a little bit confused. This led me to these questions:
Why did the SSO work for all the other users of the domain? Do I have to use the same user in both web.xml and setspn command? And which user to choose? What's the exact use of the SPN in the Kerberos scenario? Do I have to execute the command setspn in every windows computer or there is a way to do it just once?
This account is part of what defines the server's identity within Kerberos.
Kerberos is a symmetric-key protocol. Each user has a symmetric key that's shared between the user and the KDC, and similarly each service (acceptor) has a symmetric key that's shared between the service and the KDC.
When a user requests tickets for a specific "service principal", the KDC will return them encrypted using that service's key. So in order for a service to decrypt those Kerberos tickets, it also needs some way to know the key associated with its own service principal.
Often, the service key is generated randomly and provided through a "keytab" file. However, in Active Directory systems, most service accounts are regular user accounts which have a password – so their key can be derived from the service's password instead.
It seems that your SPNEGO module supports both methods (see lines 150-160) – it can be given a keytab or a password.
In any case, the setting has absolutely nothing to do with the clients that will be connecting to your service. It only establishes the server's own identity.
What's the exact use of the SPN in the Kerberos scenario?
It's similar to the domain name field in HTTPS certificates. For example, when a browser performs Kerberos authentication to https://example.com, it will always request a Kerberos ticket for the SPN HTTP/example.com from the KDC.
If you're familiar with OAuth2 or SAML or JWTs, I believe the Kerberos SPN would be the rough equivalent of the "audience" field in SAML assertions, or the "aud" field in JWTs.
(Note that the browser only knows your service by its SPN, and doesn't care about the actual service accounts that are used behind the scenes – e.g. Active Directory happens to map SPNs to real "user" accounts in this case, but other Kerberos implementations do it differently)
Do I have to use the same user in both web.xml and setspn command?
Yes, it needs to be the same user, because the service must be able to decrypt tickets that were issued for its SPN, so it needs to know the same symmetric key.
And which user to choose?
Create a new, dedicated account just for that service. Do not use a real "person" account.
Use a long, highly random password, and mark it as non-expiring. Additionally, make sure to enable both "Account supports Kerberos AES xxx-bit" features in the account's options (assuming your Java SPNEGO thing supports AES, which it really ought to).
Do I have to execute the command setspn in every windows computer or there is a way to do it just once?
No, it doesn't matter where you execute it, because it only edits the actual account on the domain controllers – it leaves no trace on the local machine. (Specifically, it sets the servicePrincipalName LDAP attribute for the provided account.)
Clients only recognize your service by its SPN, and they have no need to know about the account mapping that's done by the KDC behind the scenes.
I’ve written an OPC UA Client and i’m using ProSys OPC UA Simulator Server to test it. Running in Anonymous mode my client connects and i can browse the server. however when I configure my client to use a Username and Password it fails with No Suitable UserTokenPolicy found for the possible endPoints. I’ve debugged it and it appears that http://opcfoundation.org/UA/Se…..olicy#None is not in the endpoints userIdentityTokens array, although in ProSys it states it is.
I’ve set up a user in The OPC UA Simulator Username & Passord box is ticked
Security Modes = None
Security Policies = None are ticked
The list of server EndPoints
Security Mode = None
Security Policy = None
So i would expect to see it in userIdentityTokens array.
My Client is written using the Open62541 libraries
Any help would be appreciated.
Thanks
I haven't used the Open62541 libraries, but it seems the standard allows the OPC server to require that the username and password are encrypted even when the rest of the transport is not signed or encrypted.
It appears that at some point in time (and maybe still), Open62541 doesn't handle encrypting the password. Here are a couple of related github issues:
https://github.com/open62541/open62541/issues/934
https://github.com/open62541/open62541/issues/1548
https://github.com/open62541/open62541/issues/2757
I am working on a node.js OPC UA client based on the node-opcua library, and I was able to verify that I can connect to the ProSys OPC-UA simulation server with the security mode set to none and user authentication set to username & password. I do not know what type of password encryption node-opcua is doing behind the scenes, but it works.
----- Additional info -------
I found another forum with some clarification: https://forum.prosysopc.com/forum/opc-ua/clarification-on-opensecurechannel-messages-and-x509identitytoken-specifications/
The key part:
If passwords are sent, they will be encrypted as defined by the
UserTokenPolicy (which is separate from SecurityPolicy, but similar).
The Application Instance Certificates will be used for the encryption
in this case – and therefore they are required to be exchanged even
when MessageSecurityMode=None.
We have a client/server based application that is developed internally. Clients and server communicate over a TCP/IP connection with an application-specific protocol. The clients run on Windows and the server runs on Linux. All machines are in the same Active Directory/Kerberos domain/realm.
Currently, the user enters a username and password when they start the application. The server checks the username and password (authentication). Based on the username, the server also determines access to resources (authorization).
We want to add Single Sign-On (SSO) capabilities to the application. That is, we do not want the user to enter a username and password but we want to automatically logon as the current Windows user.
Of course, determining the current Windows user has to be done securely.
I have come up with the following setup:
I use SSPI (Negotiate) on Windows and GSSAPI on Linux.
When the client connects to the server, it uses AcquireCredentialsHandle (Negotiate) to get the credentials of the current Windows user.
The client uses InitializeSecurityContext (Negotiate) to generate a token based on these credentials.
The client sends the token to the server.
The server uses gss_acquire_cred() to get the credentials of the service. These are stored in a .keytab file.
The server receives the token from the client.
The server uses gss_accept_sec_context() to process the token. This call also returns the "source name", that is the current Windows user of the client.
The server uses the "source name" as the username: the server performs no additional authentication. The server still performs authorization.
This works but I do have some questions:
Is this secure? It should not be possible for the client to specify any other username than the Windows user of the client process. If a user has the credentials to create a process as another user (either legally or illegally) than this is allowed.
Should I perform additional checks to verify the username?
Are there alternative ways to achieve SSO in this setup? What are their pros and cons?
What you've described here is the correct way to authenticate the user. You should not have to worry about the user specifying a different name; that's what Kerberos takes care of for you.
If the client is able to obtain a service ticket, then they must have been able to authenticate against the KDC (Active Directory). The KDC creates a service ticket that includes the user's name, and encrypts it with the service's secret key.
The client would not be able to create a ticket for the server with a fake name, because it doesn't have the necessary key to encrypt the ticket.
Of course, this all assumes that you've set everything up correctly; the client should not have access to the service's keytab file for example, and the service should not have any principals in its key tab except its own.
There's a pretty detailed explanation of how it works here.
Does kerberos encrypt only the authentication process or all client communications?
I was under the impression it was like a VPN for the LAN.
So that all LAN communications are encrypted. Just like all internet communications are encrypted with a VPN.
Regards
Aubrey
Kerberos is quite capable of encrypting traffic between client and server, but depending on exactly how kerberos is used in the application, it may or may not be using the kerberos session keys to encrypt the traffic.
The kerberos protocol provides the means to exchange a session key that can be used to encrypt message traffic after the initial authentication exchange. Encrypted message exchange is generally the default for protocols that actually use GSSAPI. See gss_wrap documentation
GSSAPI is a generalized API for doing secure network applications. Kerberos is the mostly commonly used driver underneath GSSAPI.
If the application does not use GSSAPI, or the native kerberos messaging libraries, then it is likely using TLS to encrypt the traffic or the traffic is not encrypted.
Kerberos message encryption was designed to support relatively long lived tcp based client/server applications ( think telnet or ssh ). The API does not always map well to the way current applications are architected. Kerberos support is often bolted on well after the application is under construction
and is only used for authentication.
Kerberos is an distributed service that is generally used for secure authentication only. It does neither ensure that a user has the required permissions to access a resource (that would be Authorization) however it may be used to encrypt arbitrary data. As per RFC 3961 "Encryption and Checksum Specifications" which extends and correct aspects of RFC 1510 the Kerberos protocol provides confidentiality and integrity services.
While Kerberos can be used to encrypt information passed between authenticated peers in many cases it only performs the authentication step. Thus, you will find that Kerberos is used as component in a secure environment to ensure a secure authentication with other components and protocols handling the authorization and the secure transport.
In the end, it heavily depends on your usa-case to determine if the tradeoffs between using Kerberos or something else as a transport protocol make sense for you.
While the Kerberos protocol can be used to provide encryption services on most platforms, microsoft provides no mechanism to do this directory. Instead GSSAPI may be used to call these services.
For example, Active Directory uses Kerberos for message integrity.
Similarly, you could use e.g. TLS or IPsec to encrypt your data on the wire and combine it with Kerberos for authentication. But again, this is another protocol performing the actual transport encryption and just using Kerberos as an authentication component.
As I understand it,
SPN is an authenticating tool for windows services.
Kerberos is a
user authentication service
SPNEGO-GSSAPI is the third party API to
be able to use those services.
SSPI : is the Neutral layer to send
request from SPNEGO to SPN service.
Am I completely lost?
Trying to figure out how it works but information, is either too precise or not enough.
Ok a more verbose answer:-
SPN - Service Principal Name. It is an identifier associated with each account in a KDC implementation(AD, OpenLDAP etc). Basically if your account acts as a service to which a client authenticates, the client has to specify "who" it wants to communicate to. This "who" identifier is the SPN. This is the strict definition. Many people often call the client name (UPN - User Principal Name) of a service as SPN. This happens when the service itself may act as a client( google the delegation scenario ). This is not strictly correct but widely assumed true.
Kerberos is a protocol for authentication. It is a name for a framework. It involves a third party server(called KDC or Key Distribution Centre) and involves a series of steps of acquiring tickets(tokens of authentication). It is really complicated so http://en.wikipedia.org/wiki/Kerberos_(protocol)
To some extent you got this right. GSSAPI is an API but SPNEGO is not. GSSAPI is technically agnostic to the auth mechanism you use, but most folks use it for kerberos authentication. SPNEGO is a pseudo mechanism, in the sense it declares an RFC for authentication based communication in HTTP domain. Strictly speaking SPNEGO is a specification but most folks also consider it as an implementation. For instance, Sun and IBM JDK provides "mechanism providers" for SPNEGO token generation but GSSAPI is used to actually call it. This is done in many projects(Tomcat as a Server is and example that come to the top of my head and one of the folks who answered this question developed it).
SSPI is an analogue to GSSAPI in windows. Its a different API which ends up doing something very similar to GSSAPI.
Not quite.
SPN simply means 'Server Principal Name' and is the AD or Kerberos slang for the service you try to authenticate against.
Kerberos is a user authentication service, more or less yes. It also provides security for network messages and calls between services.
SPNEGO-GSSAPI* is a kind of strange beast. GSSAPI (Generic Security Service Application Program Interface) is an API to (in principle) different authentication services, it provides negotiation of the mechanisms used. Often the only mechanism available will be Kerberos though. It is the usual API to attach 3rd party programs to Kerberos when you are on Unix (defined in various RFCs, for example RFC 2743 )
On the windows platform SSPI is the generic layer, so it compares to GSSAPI.
SPNEGO is kind of a strange hybrid. It is a mechanism to be used in SSPI, HTTP Auth or GSSAPI which negotiates another auth protocol (for example Kerberos or NTLM if you are on Windows), so it basically does the same thing GSSAPI does again in a different way.
Typical uses of SPNEGO are HTTP authentication to a windows domain, for example IIS uses it if you use 'Integrated windows authentication'. It is also used when you select the 'Negotiate' options for SSPI. See for example RFC 4559
Almost all of your understandings are wrong.
Here it goes:
SPN: A specific service-class is bound to a specific account, e.g. HTTP to www.stackoverflow.com => HTTP/www.stackoverflow.com#STACKOVERFLOW.COM
Yes
3./4. GSS-API (Unix)/SSPI (Windows): Mechanism neutral API to interact with. E.g, Kerberos 5, NTLM, SPNEGO, etc.
SPNEGO: It is one of many mechnisms supported by GSS-API/SSPI. It is actually a pseudo-mech.