[edit: Caleb points out that I could be clearer in stating that using just the PPID for authenticating requests is truly a bad idea, and I have to agree. Language hardening in progress..]
In short: When you register users by using their information cards, storing the Unique ID is better than just saving the PPID. Actually, just resorting to the PPID is strongly discouraged.
And here it comes the explanation :-)
You already know what is a PPID. A PPID, or Private Personal Identifier, is an ID that identifies a specific card for a certain relying party. In case of a self issued card, Cardspace itself calculates the PPID as a combination of the reying party certificate and something unique about the card. It is the only claim in a self issued card that is automatically calculated, as opposed to be provided by the card's owner. The presence of the PPID claim can be required by a relying party by mentiong the URI "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier" in the list of the mandatory claims.A PPID is a very useful item: one card will always send different PPIDs to different relying parties, so that even if a hacker steals the PPID for RP A there's no way that such PPID will useful also for RP B. It travel in an encrypted token, so that man in the middle attacks cannot access it. Finally, it is not shown in full in the UI so that social engineeering attacks in which the user is tricked into reading it out loud are not possible.With all those good things about it, it's not surprising that the PPID is used in so many cardspace examples as the information stored during new user's sign up operations. During the registration process the website/webservice asks for a token containing the PPID: the user chooses one card, sends the corresponding token and saves the PPID in the user db. During returning visits, the user is once again asked to choose a card featuring the PPID claim: the website just compares the PPID with what was stored in the db, and if they match bingo! You're in. That's nice, and it's definitely better than username and password. But it's not as good as it can get.
In the end , a PPID is just a claim: it is not involved (directly) in cryptographic operations performed on (or with) the token. That usually means that until the PPID stays a secret we're safe, but if something goes wrong we could have troubles. It is true that the PPID is protected from generation to transmission, but once it reaches the RP in form of claim it is as secure as the RP chooses to protect it. If somebody breaks on the user DB, or if a disgruntled employee decides to make some ID sweeping, if the tables are not properly encrypted the PPID can be acquired. At this point, our bad guy has all the means for signing in. If the RP does not mandate an issuer, for example, the bad guy can write his own STS and assign the stolen PPID to his own managed cards: if the RP checks just the claim value, it will accept it as a succesful sign in. If the RP mandates a selfissued card things are harder but still possible: in this case the bad guy will have to avoid using the cardspace UI and craft the token himself, taking care to embed the right claim.Why is all this possible? Because we are just relying on a shared secret, the PPID: we take advantage of cryptographic operations just for keeping the token unreadable and unmodifiable by non-authorized, but we don't really leverage it in the details of authentication. However, those operations DO take place: to name one, the token we receive will always be signed by the token issuer. That operation can be performed by the issuer and the issuer only, since it's the sole owner of his private key: if during the user registration process we can somehow capture in a secure way the identity of the issuer, we would not be relying just on a shared secret anymore. To make the concept more concrete, consider an example in which, instead of saving just the PPID during the new user registration, we save a combination of the PPID and the public key of the token issuer. In that case, during a returning visit we would chech the value of the claim AND the key that was used for signing the token itself: while the PPID can be acquired, as described above, the signature cannot be faked. The only way of signing in is obtaining a token from the issuer that was used during the registration, and in the case of self issued cards this means that only the use of the original card will grant access. :-)Note also that nothing prevents you from storing ALSO the PPID: that may come in handy if your user has troubles, since a sinmplified version fo the PPID is shown in the Cardspace UI and can be a useful moniker for support calls.
The good news is that the current examples on the community website makes it super easy for you to leverage the above. Garrett's TokenProcessor class demonstrates the use of the member UniqueID, which is exactly a combination of the PPID and cryptographic material associated with the token issuer. It even features a configuration plug that you can use for varying the claims from which the UniqueID gets constructed! And speaking of Garrett, we had various discussions on the subject: I believe he'll sooner or later write a detailed post on the subject, as soon as he'll do I'll add the relevant link here.
So, it's 1:37 AM and I better go to sleep: let's summarize.
If you have questions, do not hesitate to drop me a line. If it's not too clear, I will be happy to update the post with one of my signature diagrams :)
I'm wondering what happens if the IP's cert changes (perhaps the private key is compromised)? With a bit of co-ordination, you can update your copy of their public key, so you can still verify incoming tokens, but would the unique id now be incorrect? Is this even a situation that can happen?
The comments to my blog stopped working. I am working on it, but in the meanwhile here there's the answer
I have finally posted my PPID information.
Garrett Serack | CardSpace Community PM | f e a r t h e c o w b o y
I was on my way up to Glasgow today to talk at an MSDN event about Framework V3.0 and it meant that I...
In short: I discuss a new feature, introduced by the .NET framework 3.5 and by a (future) update of IE,
Already Sunday evening. It was a weird weekend, partially spent under the influx of powerful pain killers
Certificates, Information Cards, PPIDs and misconceptions.
In short: I show a simple class that checks the signature of self issued tokens sent on a normal HTTP