[Edited 5/10/9: Be sure to also read Vittorio's detailed explanation about what proof keys are.]
In my last post on Geneva-related terminology, I intentionally postponed defining the term proof key. It is an important one, so I wanted to dig into it a bit more before trying to define it. Since then, I've reread Michele Bustamante's article wherein she discusses the different types of tokens and I've also clarified my understanding with Hervey Wilson, architect for the Geneva product line. After doing so, this is my current understanding of proof keys.
A proof key is a cryptographic key that allows you to create a digital signature. There are two types of tokens used in WS-Trust and WS-Federation:
- Bearer tokens
- Holder-of-key tokens
Bearer tokens do not have proof keys while holder-of-key tokens do.
The following process describes how the proof key included in a holder-of-key token is used to ensure that messages sent from subject to RP are indeed from the subject claiming to have sent them. This protocol-level protection guards against man in the middle attacks:
When creating RSTRs, the STS encrypts both the SAML token and the proof key within it using the public key of the RP. The STS also includes the proof key in the RSTR and encrypts it using the public key of the subject. Upon receiving this, the subject is able to decrypt the proof key. It then sends the SAML token and a message that it signed with the proof key to the RP. When the RP receives the message, it is able to decrypt the SAML token using its private key. It computes the signature of the token using the public key of the STS and compares it to the one included in the token. If they match, the RP knows that the token was sent by the STS and that the proof key in the SAML token is trustworthy. It then uses this to sign the message. If it matches the signature created by subject using the proof key, the RP knows that the message originated from the subject claiming to have sent it and no one else.
The anatomy of the RSTR was depicted in Michele Bustamante's recent article in MSDN about creating a custom STS which is reprinted below for conveyance:
This is all wonderful, but there's a problem: every passive client (i.e., Web browser) requests bearer tokens from the STS. Thus, the RP has no way of using the protocol described above to protect against man in the middle attacks. Why? Because Web browser doesn't know how to retrieve proof keys out of RSTRs. Even when an Info Card selector is used, a bearer token is still created. (It seems to me that the selector could get the proof key out of the RSTR and sign the message with the proof key before sending it to the RP; however, from what I understand, this isn't done for reasons unbeknownst to me.)
Because passive, browser-based clients can only work with bearer tokens, they need a way to protect against man in the middle attacks. This is done by ensuring that all communication that takes place during the authentication process happens over SSL. Stop and think about that for a moment. What type of credential is being provided by the user? A username and password in many cases. When a managed Info Card is being used, even that is often secured using a username and password. So, tell me, what is the difference between all this and basic auth over SSL? Nothing. But this question (which my team and I asked ourselves) presupposes that WS-Federation Passive Profile was intended to provide a protocol with a superior level of security than its alternatives. This is not its intention. WS-Federation Passive Profile is intended to enable advanced federation of services (authentication typically). It does this using the same level of security that is trusted and accepted by many other software applications relying on basic auth over SSL. In conclusion, the absence of a proof key in a bearer token isn't a shortcoming of the protocol; it's a limitation of current browser software that leaves the RP susceptible to man in the middle attacks. This threat vector can be mitigated using SSL.