Securing Credentials in Web Services

ArchitecturepasswordsSecuritysso

I'm attempting to design a single sign on system for use in a distributed architecture. Specifically, I must provide a way for a client website (that is, a website on a different domain/server/network) to allow users to register accounts on my central system.

So, when the user takes an action on a client website, and that action is deemed to require an account, the client will produce a page (on their site/domain) where the user can register for a new account by providing an email and password.

The client must then send this information to a web service, which will register the account and return some session token type value.

The client will need to hash the password before sending it across the wire, and the webservice will require https, but this doesn't feel like it's safe enough and I need some advice on how I can implement this in the most secure way possible.

A few other bits of relevant information:

  • Ideally we'd prefer not to share any code with the client
  • We've considered just redirecting the user to a secure page on the same server as the webservice, but this is likely to be rejected for non-technical reasons.
  • We almost certainaly need to salt the password before hashing and passing it over, but that requires the client to either a) generate the salt and communicate it to us, or b) come and ask us for the salt – both feel dirty.

Any help or advice is most appreciated.

Best Answer

What exactly do you need? To be sure that the password won't be read by a man in the middle? To be sure that the man in the middle wouldn't be able to log on?

If all you want is preventing the man in the middle from reading the passwords, just hash those passwords. It's as easy as that.

You may also want to avoid the man in the middle from getting the user name. Here, you wouldn't be able to transmit only the hash, but instead, you can encrypt the user name/password pair with a public key sent to the client, given that the server will have the private key for the decryption.

If you want to prevent the man in the middle from logging on, then the task is slightly more complicated. You can still use public/private keys, but:

  • either the public key should be communicated in advance to the consumer of the web service (which has a drawback of using the same key pair again and again, as well as the difficulty of transmitting the private key by some other channel where the man in the middle cannot catch it),

  • or the consumer of the web service can send a second public key which will serve for the server to encrypt its own public key in the response.

Related Topic