Notes on Web authentication enhancements

| Comments (4) |
There's obviously a lot of interest in working on various enhancements
to Web and Web Services applications. Unfortunately, after reading
the various drafts and mailing list postings produced by the proponents
of various technologies, I don't come away with the sense that people
have a common view of what is needed. This message is a first cut
at a taxonomy of requirements/features and technical options.

BACKGROUND: THE CURRENT STATE OF HTTP AUTHENTICATION
----------------------------------------------------
HTTP has two native authentication mechanisms, Basic Authentication
(passwords in the clear in an HTTP header) and Digest Authentication
(a challenge-response handshake also in the HTTP header). Both
mechanisms depend on the client proving the possession of a shared
secret string (a password in all real cases) to the server. The
server is unauthenticated.

For a variety of reasons, including bad UI on the clients, nearly
all real-world Web applications use neither mechanism but rather
use an HTML form to prompt the user for his password. This
password is then sent in the clear over the HTTP connection.
The standard security advice for how to secure this data is to
use HTTPS (HTTP over SSL/TLS) to encrypt the entire channel
and use the server's certificate to authenticate the server.
Practical difficulties with checking the certificate have led
to phishing attacks, in which the attacker gathers the user's
password and can then impersonate the user. An additional problem
is that it's hard for Web Services apps (e.g., DAV) to use this
kind of mechanism because HTML may not be involved and so if 
it works at all you end up resorting to screen-scraping.

In principle, if you run HTTPS, you can leverage HTTPS's 
client authentication mechanisms (client certificates and
"pre-shared keys") to authenticate the client, but in practice
this is not done, probably due to UI reasons and lack of
familiarity with the TLS mechanisms (this applies in particular
to PSK).



DESIRABLE FUNCTIONALITY
-----------------------
As I mentioned above, a lot of different types of functionality
have been discussed. In this section, I try to break these down
into a set of somewhat independent functions, with the intention
that we can end up saying that we want a system that provides
function X and not Y. These all have sort of lame names that I
thought of on the spot.


1. Capture-Resistant Credentials (CRC)
Credentials which are designed so that if you authenticate
to relying party (RP) X, X cannot use them to impersonate you to RP Y
(even if your intention was to go to Y). Phishing is based
on the fact that passwords do not have this property.
The rationale for this feature is to make phishing-type
attacks difficult.

2. Hijack-Resistant Authentication (HRA)
An authentication system in which credentials which are bound to
protocol messages in such a way that attacker who observes the
credentials can't use them to authenticate messages of their
choice. The rationale for this feature is to make cut-and-paste
attacks difficult.

3. Portable Credentials (PC)
The nice thing about passwords is that you can memorize your
password and then use it anywhere. The rationale for this is 
to make it easy for people to use credentials on multiple
computers.

4. Fill-in of Personal Information (FPI)
One of the common complaints about Web form registration systems
is the need to repeatedly type in your user information. Think of this
as automatic form fill-in on steroids. The rationale for this
feature is to avoid repeated typing of this kind of information.

5. Common User Credentials (CUC)
One way to limit the damage from credential compromise is to
have each RP use a separate credential and force the user
to make them independent (e.g., a separate password for each
RP.) This is inconvenient, of course. CUC means that at
the number of separate credentials that the user handles is 
small (if not 1). The rationale for this feature is to minimize
user attention and storage overhead.

6. Continuity of Identity (CI)
The ability to prove to some RP that you are the same
user as was involved in some other transaction. The rationale
for this feature is to have a cheap form of personal 
"account" for systems like blog comments, message boards,
etc.

7. User-Friendly Names (UFN)
The ability to prove possession of some non-random-appearing
name. The reason to separate this out is that one natural
way to provide CI is simply to generate some random asymmetric
key pair and use that (or its digest) as your identity. This
name is not user friendly. Note that this is the first requirement
in this list that appears to require a third party (to assign
the names). The rationale for this feature is that random names
are hard to remember.

8. Assertion of External Claims (AEC)
The ability to demonstrate some real-world fact about the user
(e.g., I am a certain age, this is my address, etc.) to the
RP. The rationale for this feature is that there are contexts
in which the relying party needs to be able to establish this
sort of information.

10. Independent Assertion of Claims (IAC)
The ability to assert claims independently so that the user
could (for instance) demonstrate their age to the RP without
without revealing their address. The rationale for this
feature is to protect the user's privacy.

11. Private Authentication (PA)
Some third-party authentication systems require an interaction
with the 3rd party for each authentication. In some such systems,
the 3rd party knows the relying party for each authentication
and the claims which were asserted. PA means that the 3rd party
does not get that information. The rationale for this feature
is to protect the user's privacy from the 3rd party.


ARCHITECTURAL CHOICES
---------------------
In this section, we survey a number of potential architectural options.
This list isn't exhaustive, but is just intended to give a flavor
of the major available choices beyond the simple two-party
username-password schemes we have now. Note that I use a lot 
of PKIX-type terminology below, but the concepts are generic
and can be extended to something more SAML-oid or
something-else-oid.


BARE CRYPTOGRAPHIC IDENTIFIER 
After username/password, probably the most familiar sort of
remote identifier is a bare public key. The way this is
used is familiar from SSH: the user generates a public key
and provides the key (or fingerprint) to the relying party
(or parties). He can then sign with the private key to
prove possession.

User                                     RP
----                                     --
[Personal Info], K_pub ->                        \  Registration
                                      <- OK      /  Phase

Sign(K_priv, Something) ->                       \  Use 
                                 <- Service      /  Phase

In the Registration phase, the user provides his registration info
to the relying party (site) along with the public key. The
RP stores the data somewhere. In the Use phase the user signs
something with his key to prove his identity.

Properties:
If properly embedded in a protocol (it's easy to get this wrong),
this scheme can provide:

CRC -- the RP only has K_pub
HRA -- you can cryptographically bind the requests to the key
CUC -- you can use the same K_pub, K_priv pair over and over
CI  -- you use the same identity every time even if nobody
       knows who you are.
PA  -- there's no third-party to know anything about the
       exchange

With an automated form fillin scheme like that specified in DIX,
you could also provide FPI. 


IDENTITY CERTIFICATES
One of the major inconveniences in dealing with bare cryptographic
identifiers is that that names look basically random: they're
just public keys or hashes of public keys. This is a particular
problem if two RPs want to communicate about a user through
some human-based protocol, i.e., "Don't trust bob@example.com"

The natural way to deal with this problem is to have certificate
authorities which are responsible for sections of the namespace and
can issue certificates with user-friendly names.

These certificates can come in two flavors:

1. Real-world identity certificates.
2. Unique-identity certificates

Real-world identity certificates are familiar from the HTTPS
world: an SSL certificate from VeriSign is an assertion that
the certificate holder is the actual owner/operator of a
given domain. A unique-identity certificate is just a promise
from a CA not to issue any other certificates with the same
username. 

Either form of identity certificate allows you to have nice
userfriendly names (or at least more userfriendly than random
numbers). The protocol looks something like this:

User                                     CA
----                                     --
[Personal Info], K_pub ->                        \  Certificate
                                      <- OK      /  Issuance


The user gets a certificate (possibly covering some personal
info) from the CA. They can then use this certificate much
in the same way they used a bare key, by registering with
the RP and then getting service. 

User                                     RP
----                                     --
[Personal Info], Cert ->                         \  Registration
                                      <- OK      /  Phase

Sign(K_priv, Something) ->                       \  Use 
                                 <- Service      /  Phase

Note that some people also think of the mere possession of a
credential, even if it has no underlying AEC semantics as
worth something. I.e., this person registered *somewhere*
and I know that about them. This makes sense in contexts like
blog comment authentication where you are just trying to erect
a minimal registration barrier.


Properties:
This scheme has most of the same properties as the bare cryptographic
identifiers, but also has at minimum User Friendly Naming (UFN).
In addition, if the certificates are real-world identity certificates,
it provides a very limited form of AEC, namely "this person has
the right to this e-mail address, domain name, etc."


SIGNATURE + KEY SERVER
Both bare cryptographic identifiers and identity certificates suffer
from portability problems. The part of your identifier that you need
available to you at authentication time is a fairly long random number
that most people won't be willing to memorize. [0] The natural
approach is to carry the data around on a token (USB key, PCMCIA
card, etc.) but this seems unattractive to many. Another option is
to use a SACRED-type server to store the key and then let the user
fetch it at whatever computer they are at. SIP is also considering
a similar technique for moving keys between handsets (see
(draft-ietf-sip-certs)

Properties:
Same as underlying authentication scheme + Portable Credentials.


ATTRIBUTE CERTIFICATES
The clear problem with all the schemes mentioned so far is that
they only provide very limited AEC, which a lot of people clearly
want. The standard solution for combining AEC with public-key-based
authentication systems is to use attribute certificates: 
certificates that assert a certain fact about the holder of key
K, such as:

"The person who holds key K is an American citizen."

In PKIX these are often (always?) tied to some actual 3rd-party
certificate but from an architectural perspective, they could be tied
to a bare key. Attribute certificates can also be used to provide
IAC: you have a bundle of attribute certs with one for each claim
you wish to assert and you simply provide the relevant certs
to the RP.

The basic protocol looks like this:


User                                     CA
----                                     --
[Personal Info], K_pub ->                        \  Certificate
                           <- AC1 (Over 21)       > Issuance
                        <- AC2 (US Citizen)      /


In the Certificate Issuance phase, the user proves to the
CA the claims that he wants the CA to vouch for and the 
CA gives him ACs for those claims. 

User                                     RP
----                                     --
Sell me beer ->                               \
                         <- Prove you're 21    \ Use
Sign(K_priv, Something), AC ->                 / Phase
                                 <- Service   /

In the use phase, the RP indicates which claims he wants the
user to demonstrate and the user provides the appropriate
ACs and demonstrates that he has the corresponding key. 
Of course, for any attributes for which you have ACs, you
also get some FPI for free as part of the authentication.

Properties:
CRC, HRA, FPI (Some), PC (if used with key server), CUC, CI,
UFN, AEC, IAC, PA


IDENTITY PROVIDERS
A lot of the designs that people seem interested in involve
Identity Providers (IdP). An IdP is a server that offers
interactive identity claims. (One way to think of this is
as a real-time CA). There are a bunch of different 
topologies, but the basic idea is as below:

User                           IdP
----                           ---
[Personal Info], Auth Info ->       \  Registration 
                             <- OK  /  Phase     

The user registers with the IdP and (optionally) proves
the claims that he wishes the IdP to assert later. The
user needs to establish some sort of authentication
credential with the IdP so that he can authenticate
later. This can be a password or a public key pair (as
above). 

Later, when he wants to actually use his identity, we
get an exchange like this:


User                      RP                       IdP
----                      --                       ---
Sell me beer ->                                         
          <- Prove you're 21

IdP, help me!                                   ->
          <---------- Auth exchange ------------->
                                         <- Credential

Credential ->              
                       <- OK
                      
When the user requests service, the RP prompts them for their
identity (or in the case above, to prove some claims). The
User then contacts the IdP and proves their identity 
(authenticates as the person who previously registered)
and gets a credential. He Then provides the credential to the
RP, who provides the service. 

There are a lot of ways to implement this general architecture
and they all have different properties. 

Properties:
At minimum, IdP based schemes provide:
PC  -- you can contact the IdP from anywhere
CUC -- you only need to authenticate to the IdP and then can 
       leverage that to authenticate everywhere
CI  -- you use the same IdP acct over and over
UFN -- the IdP can issue you some easy name

If the IdP makes claims about you, then you can also have FPI, AEC and
IAC. In general, because the IdP knows which claims you're asserting
for a given RP, you do not get PA. There are, however, ways to provide
this feature, but often the contrary is part of the design of the
system.

A lot of the variation in IdP schemes is the implementation of 
the authentication, both from the user to the IdP and from the 
IdP (and user) to the RP. There's too much variation to discuss
here, but I'll cover a few high points.


Authentication to the IdP:
Part of the point of an IdP scheme is that you authenticate to
the IdP in order to get your credentials. Obviously, this 
authentication can be done in a lot of ways. Some of them
allow phishing, credential capture, etc. It's clearly
desirable to couple an IdP scheme with some sort of
auth scheme that provides CRC and probably HRA.

Binding of credentials to requests:
In an IdP scheme, the IdP provides some token to the user that is then
provided to the RP. This token may or may not be cryptographically
bound to the messages that the user is sending to the RP. If this
is not done, then the user<->RP protocol is potentially susceptible
to hijacking.

Note that it's well understood how to design both of these protocols
securely. However, it involves more changes to the current
implementations of Web and WS protocols.


TRANSPORTING/BINDING CREDENTIALS
--------------------------------
The discussion above has focused primarily on dataflow, but
from the perspective of implementation/deployment, how you
transport and bind the credentials to the PDUs they're 
authenticating matters. Note that to some extent this is 
orthogonal to the type of authentication architecture you're
using. You can, for instance, use public key signatures
with multiple binding/transport mechanisms. 

There are three commonly proposed transport/binding methods:

CRYPTOGRAPHIC BINDING INSIDE HTTP
If you're using public key for authentication, the natural approach is
to simply have the credentials bound directly to the HTTP PDUs they
vouch for. So, the PDU would contain a signature line that covered the
request itself. This is what, for example, S-HTTP does.

In systems like this, additional credentials (ACs, SAML assertions,
etc.) are just carried in the message and the whole thing is bound
together with the signature. Something like this:

         POST / HTTP/1.0
         X-Attribute-Cert: 
         X-Signature: XXX

         Post arguments

The signature is computed over the entire message and headers (except
for the signature itself, of course), or part of it (hopefully enough
to block cut-and-paste attacks).  This kind of technique, if performed
correctly, provides both CRC and HRA for the messages between the user
and the RP.

Similar techniques can be use with symmetric keys and MACs over
the PDUs. In such schemes, if you're using an IdP, then you'll
probably also have to carry around a ticket that gives the 
RP the symmetric key needed to verify the message.

Implementing this kind of scheme would generally require a fair
amount of modification to the browser and server at least to
protect the messages. 


SSL/TLS CLIENT AUTHENTICATION
Another approach is to do things at a layer below HTTP, typically
using SSL/TLS client authentication. Currently, SSL/TLS supports
client authentication using pre-shared keys and certificates (you can
use self-signed certs as bare keys).  draft-housley-tls-authz-extns
defines how to carry X.509 ACs and SAML assertions inside of TLS, so
these could be used as well. This technique automatically provides CRC
and HRA.

In principle, TLS clients and servers already support at least
cert-based client auth. In practice, the UI on the client
is so bad that you would almost certainly need to clean it up
quite a bit in order to make this kind of system usable.


CARRIED NONCRYPTOGRAPHICALLY INSIDE HTTP
One approach that comes up quite a bit is to just embed 
authentication tokens (typically generated by an IdP) in
the HTTP messages that go from the user to the RP (DIX is
an example of such a scheme). In this system, the tokens
themselves are "bearer"--they enable any holder to impersonate
the user. In order to protect against token capture, the tokens
are generally made specific to the RP, so that one RP can't
use them to impersonate the user to another. 

An additional issue is hijacking: without cryptographic 
binding, an attacker who observes a request can make future
requests in the name of the user via a cut-and-paste attack
(remember, the token is bearer). If you take the threat of
this type of attack seriously, you need to run the traffic
over SSL/TLS. [1] 

The primary attraction of this kind of design is that it
may be implementable without changing the client software
at all (again, see DIX). Many people see that as important
for deployment. 


[0] You can use asymmetric key pairs generated from passwords,
but even with the application of key stretching techniques, this
makes a lot of people uncomfortable.

[1] Note that if you're worried about this class of attack, you need
*every* PDU to be cryptographically bound to the credential with
all designs. If, for instance, you use cert-based auth but then
transition to cookies over HTTP for state management, there's a 
cut-and-paste attack there.

4 Comments

A quibble, but - the non-user-friendliness of "bare cryptographic identifiers" seems overstated. The ugliness of most fingerprint formats is due to naive design more than anything. It's possible to design fingerprints that are fairly easy to memorize:

- Instead of resisting collision-search with long random strings, use shorter fingerprints but make coming up with candidate fingerprints more expensive (a la RFC 3972).

- Instead of hex-encoding a 160-bit value, use base32, settle for a lower security level (e.g., 112 bits), and discard candidate fingerprints until you get one with good mnemonic properties (vowels alternating with consonants, for example).

With the above techniques, you could create memorable fingerprints with a couple minutes of computation apiece [1]:

dubo9.sanre.wivip.wqsqy

cegar.hdaab.ivyr6.kznmo

drups.kixos.ruzkb.ij43c

Anyways, hopefully this shows that usability of bare identifiers isn't a lost cause or even a settled issue - it can be a lot better than most people would expect.

[1] http://trevp.net/cryptoID

A grand start! A couple of critical remarks...

"Unfortunately, after reading the various drafts and mailing list postings produced by the proponents of various technologies ..."

There's obviously been a lot of work and thought put in. You could probably improve support for this effort by quoting who these people are, and referring back to their work. Everyone loves to spread a document that they influenced.



(Generally, when a document picks up work from other people, and doesn't quote their work, it is a really good sign that the document is useless. There's a surprisingly good correlation between care in references and care in thought. Annoying and I'm often lazy myself...)
"probably due to UI reasons and lack of familiarity with the TLS mechanisms ..."

I'd say it is because the design mitigates usage. As a sometimes application programmer, it is a no-brainer that if the server has to demand the certificate and it is not automatically available, then this kills rollout. An application programmer will decline to use it. As you recognise in the 1st Architectural choice...



The document might get more support from the UI and applications community if it said something like "probably because the design does not support easy deployment."

There's obviously been a lot of work and thought put in. You could probably improve support for this effort by quoting who these people are, and referring back to their work. Everyone loves to spread a document that they influenced.
I'm not sure I understand what you're trying to say here, but this comment doesn't really match my understanding of the background or of my motivations. Many *others* have proposed a large variety of mechanisms to do things in this general space. Unfortunately, the discussion so far has been very long on technical minutiae and very short on architecture and abstraction. This message was a deliberate attempt to bring some architectural thinking to bear, a context in which I find talking about specific proposals to make matters worse, not better, since it tends to result in a lot of nitpicking about the details. Unfortunately, explaining everything from scratch is also problematic, so I compromise, using specific examples where I think they're illuminating but otherwise trying to be abstract.

As for improving "support for this effort"... What effort? I'm not selling anything and I don't expect this document to become some kind of long term thing: I'm just trying to help drain the swamp so that the people who actually want to work on the problem can do so more efficiently. If people don't think that document does that, fine by me.

(Generally, when a document picks up work from other people, and doesn't quote their work, it is a really good sign that the document is useless. There's a surprisingly good correlation between care in references and care in thought. Annoying and I'm often lazy myself...)
Care to elaborate on this point? Everything I'm saying is COMSEC 101, so I don't really see where the suggestion that I'm taking other people's work without attribution comes from.

I'd say it is because the design mitigates usage. As a sometimes application programmer, it is a no-brainer that if the server has to demand the certificate and it is not automatically available, then this kills rollout. An application programmer will decline to use it. As you recognise in the 1st Architectural choice...
This is too vague for me to understand. In TLS, client certs are optional (i.e., the connection can survive if the client refuses it) so I'm not sure what protocol support you think would be more useful here, in the face of the fact that for *any* credential mechanism there will be those who don't have that credential.

The document might get more support from the UI and applications community if it said something like "probably because the design does not support easy deployment."

See above comments about not trying to gather support.

1st broad point - I took an implication from the first paragraph that you collected up all those efforts and summarised them. My error, I did not realise you were not doing that.

2nd precise point - yes, you are right, I was confused by something else, which is probably beyond the moment.

Apologies!

Leave a comment