Why does the Kerberos protocol not feature perfect forward secrecy?
The technical reason is as follows:
The Kerberos protocol in its basic
form does not provide perfect
forward secrecy for communications.
If traffic has been recorded by an
eavesdropper, then messages encrypted
using the KRB_PRIV message, or
messages encrypted using
application-specific encryption under
keys exchanged using Kerberos can be
decrypted if the user's,
application server's, or KDC's key is
subsequently discovered. This is
because the session key used to
encrypt such messages, when
transmitted over the network, is
encrypted in the key of the
application server. It is also
encrypted under the session key from
the user's TGT when it is returned to
the user in the KRB_TGS_REP
message. The session key from the TGT
is sent to the user in the
KRB_AS_REP message encrypted in the
user's secret key and embedded in
the TGT, which was encrypted in the
key of the KDC. Applications
requiring perfect forward secrecy must
exchange keys through mechanisms
that provide such assurance, but may
use Kerberos for authentication of
the encrypted channel established
through such other means.
Basically perfect forward secrecy adds additional overhead to the protocol that is not necessary for many of its applications. If you need PFS, then you can add it. What does matter to most Kerberos users is speed. If you have tens of thousends of employes all over the world all authenticated at the same time, then the overhead required for PFS is going to be too expensive and there for not practical.
Related
Usually when a user logs in, the user details are sent to the sever to authenticate the user. How are these credentials protected in the best way during flight?
Main Questions :
I understand the passwords are many times hashed, keeping them secure. Also TLS maintains the in-flight security, But is that the only way the transaction details are kept secure or do websites add any of their own layer of security?
In our case, we want to send a passcode to the backend, where another API will be called (that uses password grant) of a third party application. We cannot hash the password, we'll need it in the backend. Will TLS be sufficient for securing it in flight?
We were also planing to implement and secure the passcode by RSA (public key) on the client side and unlock it on the backend for use. Should we consider RSA?
I understand the passwords are many times hashed, keeping them secure. Also TLS maintains the in-flight security, But is that the only way the transaction details are kept secure or do websites add any of their own layer of security?
There are very few cases where layering more cryptography on top of TLS are beneficial. Your case doesn't seem to fit them. So TLS should be enough. TLS already provides encryption in transit. RSA would do the same. Defense in depth means layering different security mechanisms on top of each other.
You might hash the password on the client side creating an intermediate password, but considering your 2. question, this is not what you can do.
In our case, we want to send a passcode to the backend, where another API will be called (that uses password grant) of a third party application. We cannot hash the password, we'll need it in the backend. Will TLS be sufficient for securing it in flight?
Yes, but let the client (your server) validate the certificate chain and don't accept protocol downgrades.
We were also planing to implement and secure the passcode by RSA (public key) on the client side and unlock it on the backend for use. Should we consider RSA?
No, just use TLS 1.2 or higher with a valid server certificate and let the client validate the certificate chain (browser does that automatically for you).
Keep in mind that TLS needs a trust root. Most client side libraries as well as many browser use the trusted root store of the operating system. A certificate chain presented by the server should end in one certificate that is in the trusted root store.
You could use a self-signed certificate, but then the client would need to pin the public key of that self-signed certificate.
We are currently designing a smartphone application that needs an authentication protocol.
We will use HTTPS for all the messages. The idea is the following :
The client contacts the server and authenticates himself with his user/password combination.
The servers replies with a ramdom-generated token that is stored in the database.
To contact the server the client now uses his/her user/token combination.
In each message he sends, the server has a certain probability to regenerate a new token that it includes in the message it sends.
The question is : will we have security issues using this protocol ?
Note : passwords and tokens are stored hashed in the database.
The security bases on the certificate you use for encryption. In general this is enough, you may also check if it is the expected certificate. In the case that you check yourself the fingerprint of the certificate you can be sure (if you use sha1 or better) that the certificate is from you and not a successful man in the middle attack. E.g. the NSA could simple create valid certificates for your domain, but AFIK it is impossible to generate a second certficate with the same fingerprint.
By the way I hope that the passwords and tokes are also salted. That is important so it is impossible to see that two customers uses the same password and also it increases the complexity of the hash, that means that it will take much more time to crack such a password with a rainbow table.
I am looking into ways of securing the channel between my client apps and the server.
I have a rich desktop client (win) and mobile client connecting to a webservice, exchanging data.
Using SSL certificates, server and clients may trust each other. On the secured connection i can exchange username and password and therefore authenticate the user.
However i have certain circumstances where a user must connect to the server via any of the two methods without his credentials but only a literal, like say, a license plate number.
I really want to make sure that in this case i ONLY allow client connects from devices i am sure i know, since there is no further checks on the authentication and a license plate number would be a pretty common literal.
How can i ensure that only "devices" which are known to my server, can interact with my server?
If you want to authenticate the device, you'll need to find a way for the device to prove what it is, without disclosing its secret.
A system similar to a number plate would be quite easy to spoof, for anyone in a position to see that number. Depending on how much control you have on this device, you might not be able to hide it, even if the connection to your server is secured with SSL/TLS.
A potential way to do this would be to use a cryptographic hardware token (or smart card). Some of these tokens can be configured to hold a certificate and private key, with the ability to use the private key without being able to export that private key. The cryptographic operations (signing and decryption) happen on the token itself.
You can use these to perform client-certificate authentication to your server. In this case, you would know that the client has that token. This could work on the condition that you know the CAs were issued its certificates only for key pairs in such tokens: there will be a cost in administering the CA to handle this.
This would at least allow you to tie the authentication to a particular token. Whether you can integrate this with your overall device depends on the kind of device you have.
Please check if TLS Pre-Shared Keys (RFC 4279) can be used for your scenario.
I am curious how to properly send username and password from a website login form to a server.
If I just send the username and password without hashing them to an https server how exposed is the password I send in a POST request to somebody sniffing the package and finding out the password? The server is https enabled.
What would be the proper methodology to do this?
If the server is HTTPS enabled then any data going over the wire will be encrypted. It would be extraordinarily difficult for a network-only attacker to sniff even a plaintext password over HTTPS without one of the parties noticing.
HTTPS uses SSL/TLS on the transport layer, which is designed to provide both encryption and authentication. The SSL/TLS protocol, as part of its handshake, negotiates a symmetric encryption key that is different for each session and is used with a strong algorithm to protect data on the wire.
To mitigate 'man-in-the-middle' attacks, the asymmetric keys used by the client and server to establish a shared encryption key are also cryptographically signed by a certificate authority, both to provide assurance of trust and to prevent modification of the certificate. As long as the certificate authority can be trusted, it is easy to check the signature and and server name on the certificate itself. All modern browsers do this automatically and throw a warning to the user if there is any problem with the certificate.
As long as you and your users are aware of the issues surrounding the proper use of SSL (e.g. keep your private key safe, and make sure your users pay attention to browser warning), it's fine to send plaintext passwords over an SSL connection.
If the demands of your application are such that you cannot do even that, you might consider X.509 authentication (which uses certificates on the client side as well as the server side) or Kerberos authentication (which sends no passwords over the wire). For a basic web application, though, both of these solutions are overkill.
Our clients call our web service over SSL and authenticate themselves with a username and password. Our server then generates a symmetric key and sends it back to the client.
Then, the client establishes a TCP connection to our server, and sends a login message. At this point, I want to authenticate the client.
My idea is to have the client encrypt a well-known/static piece of text with the symmetric key and use this as proof that it is in possession of the key.
Since the symmetric key is generated randomly, is it ok that I use a static piece of text here?
Any input appreciated.
SSL is built to authenticate both client and server, and asymmetric cryptography the most secure primitive you can use in this scenario. Symmetric ciphers can be used for authentication by using a Cipher Block Chaining Message Authentication Code other wise known as CBC-MAC mode. The use of CBC-MAC has similar protection as an HMAC, but utilizing a symmetric cipher instead of a message digest function. CBC-MAC mode is used by WPA to protect wireless networks.
Your idea is subject to a replay attack - if someone observes a user logging in, they can store the static-text-encrypted-with-symmetric-key and use it later to authenticate themselves.
The accepted way of doing this is a challenge/response. The client connects, the server generates a random challenge and sends it to the client, and the client responds with the encrypted version of the challenge (although you should actually use a HMAC here, rather than a block cipher, because otherwise your client is effectively a one-block decryption oracle!). It would also be safer to use two different random keys (provided at the same time over the web service), one for encryption and one for authentication.
Note though that this scheme, as written, is still susceptible to a man-in-the-middle attack. You are definitely better off using SSL, as The Rook suggests. This will require your client to generate a public key and send it to the web service. The web service responds with a signed certificate containing the client's public key along with the client's unique identifier (username, or whatever) in the DN field. The server on the separate connection verifies the client certificate used (ensuring it's signed by your web service), and verifies that the client identifier in the certificate matches the client that is asking to connect.