RSA would really be the best way to go here, but indeed there's no implementation in either the Silverlight 2 or 3 libraries. It's something that really should have been added in my opinion, though it's very unlikely to happen until Silverlight 4 now. Unfortunately, a custom RSA implementation is likely to be truly painful, so it's not quite feasible I'd expect.
Here is my proposed solution... It's certainly not as simple as simply sending the public key from the server, but it should do the job securely still.
- Use the Diffie-Hellman key exchange algorithm to agree on a key to be used for later encrypted. This was designed to work over an insecure channel, so there are no problems here. See here for a C# implementation.
- Use some sort symmetric encryption with the key established by the Diffie-Hellman exchange to send the username/password over the connection. The server can then decrypt using the same key, which while known to both the client and server, are nonetheless unknown to any third party. The strength of your symmetric encryption algorithm should not in fact matter in this case. (Someone correct me if I'm wrong.) A simple XOR cipher should do the job in fact. It seems you could also use the AES standard, which is included in the
System.Security.Cryptography
namespace of the Silverlight BCL.
Hope that helps. Let me know if you're not clear on any of the points.