A days Cryptowork with ASP.NET and Remoting
Sending password and such over remoting feels a bit unsafe. In the first release of the user management system I'm working on, this was not a top priority to cover, but sooner than first assumed I had to implement cryptography in each end of the line. I am no big cahuña on crypto and frankly all these terms scares me a bit. SHA. DES & TripleDES, MD5, DSA, RSA, Rijndael and more. It's a whole new world of TBA's. I read that the AES (Advanced Encryption Standard) algorithms were the coolest ones, so I went with Rijndael.
My solution implements an Authenticate(username, password) method that returns a string generated by the FormsAuthentication.Encrypt. This worked like a charm on my local development machine, where the remoting client and server ran on the same IIS. But when the remoting client moved this naturally crashed. The errormessage was a CryptographicException: Bad Data, described here. FormsAuthentication.Encrypt/Decrypt uses 3DES (TripleDES) to crypt the FormsAuthentication cookie, and 3DES uses an encryptionkey based on the local machine, so encrypting on one machine and decrypting on the next is no great idea.
This is possible to ovveride though. You just have to add a
Giving up on that approach, and thinking that crypto can be used for other things in my app aswell (like crypting passwords before writing them to the database) I found this article by Mark Strawmyer and a QuickStarter. Mark gives a nice intro to .NET cryptography and have almost all the code you need. I copied it, but had to write the Decrypt() method (want it? code here). At first it annoyed me that he hadn't included the Decypt code, but now I'm pleased to have a bit more overview of the System.Security.Cryptography namespace (plus actually being able to write C r y p t o g r a p h y in less than 5 seconds).
The coolest thing about it was that I get to use a SecretPhrase in the config file on the server that the client needs to match in its config. Otherwise the decrypt will fail.
Finally I went back to my Authenticate(username, password) method and slapped my new Encrypt/Decrypt methods around the password on each side of the wire. But I still had to transfer all the information that was contained in the FormsAuthenticationTicket over the wire encrypted. And using the built in string FormsAuthentication.Decrypt won't work.
I wrote two new methods in my crypto-class for the FormsAuthenticationTicket. EncryptTicket and DecryptTicket. These simply use the BinaryFormatter to serialize the ticket object to a stream and create base64 strings of them to be encrypted with Rijndael (should be pretty safe right?).